Both ends say AES-128 and the tunnel still refuses to build. Cipher-block chaining and Galois/counter mode are different transforms that happen to share a key length, and a client offering one does not satisfy a gateway that accepts only the other. The word AES describes a family, not an agreement.

There is a second axis as well, and it is the one that produces confusing errors.

Two Layers, Two Independent Lists

IKE protects the negotiation itself, while the child association protects the traffic you actually care about. Windows exposes the first as an encryption method and an integrity method, and the second as cipher and authentication transform constants. Those fields are not aliases for each other, and a value valid in one may be meaningless or wrong in the other. Reading the profile with that split in mind removes most of the confusion.

The practical consequence is that you can have a perfectly acceptable key-exchange policy and a data-channel policy the peer will not accept. One list negotiates; the other protects packets. Changing a value in the first has no effect on the second, however similar the two look in a configuration dialog.

Write both lists down before you compare them with the gateway. A comparison performed from memory is how one field gets edited twice and the other never. Keep the gateway console open beside the profile.

Read the Error Beside the Proposals

The stage that failed tells you which list to examine. A refusal during the initial key exchange is an IKE proposal problem, and it happens before any child association exists. A failure while the protected-traffic association is being negotiated is an ESP proposal problem, and the key exchange already succeeded. A generic policy-match message from the client names neither stage, which is why the gateway's own view is the useful one.

swanctl --list-conns
swanctl --list-sas
journalctl -u strongswan -n 60 --no-pager

Compare the received proposal, the configured proposal and the selected one for that single attempt. Three different lists matter here, and only the last one describes what actually got used. Quote it verbatim in the ticket rather than summarising it.

Keep CBC and GCM as Separate Alternatives

A gateway deliberately allowed to accept either family needs two proposals, not one. In strongSwan a comma separates alternatives, and a hyphen joins the components of a single suite. Combining both families with hyphens produces one impossible proposal rather than two acceptable ones.

proposals = aes128gcm16-prfsha256-ecp256, aes128-sha256-ecp256
esp_proposals = aes128gcm16-ecp256

The first alternative carries authenticated encryption and still names a pseudorandom function, because key derivation needs one even when integrity comes from the cipher. The second alternative is classic encryption with a separate integrity algorithm. Both remain subject to what the loaded crypto implementation supports.

An ESP Proposal Is Not a Renamed IKE Proposal

The cipher token looks identical in both lists, and almost nothing else carries over. An ESP proposal has no key-exchange pseudorandom function, and its integrity and forward-secrecy requirements are argued against the Windows policy on the other side rather than copied from the IKE line. Mechanically translating one list into the other produces something that validates and never negotiates.

Pick a direction and stay in it. Either the gateway keeps a GCM-only policy and the client deploys a complete compatible policy, or the gateway accepts both families and the client keeps its existing suite. Enabling a fallback the security policy forbids is not a fix, however quickly it clears the error.

Verify Both Suites, Then a Rekey

Confirm the selected key-exchange suite and the selected traffic suite separately, because they come from different lists and can succeed independently. Then let a rekey happen and confirm it too. A first handshake that works and a rekey that fails describes a proposal set that is only partially acceptable.

Keep that evidence with the change. A recurring disconnect needs its own failed-exchange record before anyone blames a timer or a platform defect.

Sɛbɛn minnu bɛ tali kɛ