{"record":{"id":"da9633a441c34f41","repo":"caddyserver/caddy","slug":"unsupported-cipher-suite-s","errorCode":null,"errorMessage":"unsupported cipher suite: %s","messagePattern":"unsupported cipher suite: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/connpolicy.go","lineNumber":345,"sourceCode":"\t\t// session ticket key rotation\n\t\ttlsApp.SessionTickets.register(cfg)\n\t\tctx.OnCancel(func() {\n\t\t\t// do cleanup when the context is canceled because,\n\t\t\t// though unlikely, it is possible that a context\n\t\t\t// needing a TLS server config could exist for less\n\t\t\t// than the lifetime of the whole app\n\t\t\ttlsApp.SessionTickets.unregister(cfg)\n\t\t})\n\t}\n\n\t// TODO: Clean up session ticket active locks in storage if app (or process) is being closed!\n\n\t// add all the cipher suites in order, without duplicates\n\tcipherSuitesAdded := make(map[uint16]struct{})\n\tfor _, csName := range p.CipherSuites {\n\t\tcsID := CipherSuiteID(csName)\n\t\tif csID == 0 {\n\t\t\treturn fmt.Errorf(\"unsupported cipher suite: %s\", csName)\n\t\t}\n\t\tif _, ok := cipherSuitesAdded[csID]; !ok {\n\t\t\tcipherSuitesAdded[csID] = struct{}{}\n\t\t\tcfg.CipherSuites = append(cfg.CipherSuites, csID)\n\t\t}\n\t}\n\n\t// add all the curve preferences in order, without duplicates\n\tcurvesAdded := make(map[tls.CurveID]struct{})\n\tfor _, curveName := range p.Curves {\n\t\tcurveID := SupportedCurves[curveName]\n\t\tif _, ok := curvesAdded[curveID]; !ok {\n\t\t\tcurvesAdded[curveID] = struct{}{}\n\t\t\tcfg.CurvePreferences = append(cfg.CurvePreferences, curveID)\n\t\t}\n\t}\n\n\t// ensure ALPN includes the ACME TLS-ALPN protocol","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/connpolicy.go#L327-L363","documentation":"Returned by buildStandardTLSConfig when a ciphers/cipher_suites entry is not found in the supported list (CipherSuiteID returns 0). Caddy only accepts the IANA-style names it has registered; TLS 1.3 suites are not configurable in Go's TLS stack, and unknown or misspelled names fail here.","triggerScenarios":"A tls block listing a cipher name not in the supported map: misspellings, older GCM names, TLS 1.3 suite names (TLS_AES_128_GCM_SHA256 etc.), or names from other servers' docs. Applies per connection policy during Provision.","commonSituations":"Copying cipher lists from nginx/Apache/Mozilla SSL config generator output that includes names Caddy/Go do not support; hardening guides mixing TLS 1.2 and 1.3 suites; trailing whitespace or case differences.","solutions":["Remove the offending name shown in the error","Restrict cipher lists to TLS 1.2 suites from Go's supported set and drop TLS_AES_/TLS_CHACHA20_ names (1.3 suites are always-on)","Re-copy a known-good list from Caddy's documentation","Validate config with 'caddy validate' after editing"],"exampleFix":"# before\ntls {\n\tciphers TLS_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\n}\n\n# after (TLS 1.3 suites are not configurable)\ntls {\n\tciphers TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\n}","handlingStrategy":"validation","validationCode":"// In Go, validate names against Caddy's registry before accepting user input:\nfunc validCipher(name string) bool {\n\treturn caddytls.CipherSuiteID(name) != 0\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Copy cipher lists only from Caddy's own docs, not nginx/Mozilla generator output","Never include TLS 1.3 suite names — Go enables them unconditionally","Lint configs for cipher names against 'caddy list-modules'-adjacent docs in CI"],"tags":["caddy","tls","cipher-suites","configuration","validation"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}