Transactions with low fees may remain in the mempool for as long as 14 days. This indeterminism is a source of confusion for users and wallets. It's not possible to cause a transaction in the mempool to expire (become invalid) at a certain time in the future, if not yet mined.
Allowing a transaction to specify a block height after which it cannot be mined would provide certainty around how long a transaction has to confirm before it is rejected by the network and must be re-sent. This would allow a payment to be re-attempted without having to wait up to 14 days and without having to satisfy the BIP125 rules or submitting a CPFP transaction. This would also have the advantage of optimizing mempool performance by removing transactions that are no longer desired or that may not be mined.
Adding this functionality today would probably require a hard fork, but why didn't the protocol initially provide this feature?