caddyserver/caddy · error

invalid AEAD ID: %d

Error message

invalid AEAD ID: %d

What it means

Twin of the KDF check: each AEAD ID in the cipher-suite list is validated with hpke.AEAD(id).IsValid(). Caddy generates AES128GCM (0x0001) and ChaCha20Poly1305 (0x0003); any other value (or garbage) in a stored config fails with the numeric ID in the message.

Source

Thrown at modules/caddytls/ech.go:1016

	var err error
	if echCfg.PublicKey, err = echCfg.KEMID.Scheme().UnmarshalBinaryPublicKey(pk); err != nil {
		return fmt.Errorf("parsing public_key: %w", err)
	}

	echCfg.CipherSuites = echCfg.CipherSuites[:0]

	for !t.Empty() {
		var hpkeKDF, hpkeAEAD uint16
		if !t.ReadUint16(&hpkeKDF) || !t.ReadUint16(&hpkeAEAD) {
			// we have already checked that the length is divisible by 4
			panic("this must not happen")
		}
		if !hpke.KDF(hpkeKDF).IsValid() {
			return fmt.Errorf("invalid KDF ID: %d", hpkeKDF)
		}
		if !hpke.AEAD(hpkeAEAD).IsValid() {
			return fmt.Errorf("invalid AEAD ID: %d", hpkeAEAD)
		}
		echCfg.CipherSuites = append(echCfg.CipherSuites, hpkeSymmetricCipherSuite{
			KDFID:  hpke.KDF(hpkeKDF),
			AEADID: hpke.AEAD(hpkeAEAD),
		})
	}

	var rawPublicName []byte
	if !content.ReadUint8(&echCfg.MaxNameLength) ||
		!content.ReadUint8LengthPrefixed(&t) ||
		!t.ReadBytes(&rawPublicName, len(t)) ||
		!content.ReadUint16LengthPrefixed(&t) ||
		!t.ReadBytes(&echCfg.RawExtensions, len(t)) ||
		!content.Empty() {
		return errInvalidLen
	}
	echCfg.RawPublicName = string(rawPublicName)

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Delete the affected stored ECH configs so Caddy re-creates them with AES128GCM + ChaCha20Poly1305.
  2. Restrict imported configs to those two AEADs.
  3. Update Caddy if the AEAD is legitimately supported in newer hpke.
Defensive patterns

Strategy: validation

Try / catch

if err != nil && strings.Contains(err.Error(), "invalid AEAD ID") {
    // prune stored configs; regenerate with AES128GCM/ChaCha20Poly1305 suites
}

Prevention

When it happens

Trigger: Decoding an ECH config whose AEAD list contains IDs not registered in the hpke package — corruption or configs authored by other stacks using AES256GCM-only/other AEADs depending on hpke's registry.

Common situations: Corrupt ech/configs entries; imported ECH config blobs with unsupported AEAD sets; hpke version differences across Caddy builds.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/227c505b1c0e6640. Report an issue: GitHub.