{"record":{"id":"d5b6c24af1411ed9","repo":"caddyserver/caddy","slug":"invalid-tls-renegotiation-level-v-d5b6c2","errorCode":null,"errorMessage":"invalid TLS renegotiation level: %v","messagePattern":"invalid TLS renegotiation level: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/capools.go","lineNumber":617,"sourceCode":"\tif t.CARaw != nil {\n\t\tcaRaw, err := ctx.LoadModule(t, \"CARaw\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tca := caRaw.(CA)\n\t\tcfg.RootCAs = ca.CertPool()\n\t}\n\n\t// Renegotiation\n\tswitch t.Renegotiation {\n\tcase \"never\", \"\":\n\t\tcfg.Renegotiation = tls.RenegotiateNever\n\tcase \"once\":\n\t\tcfg.Renegotiation = tls.RenegotiateOnceAsClient\n\tcase \"freely\":\n\t\tcfg.Renegotiation = tls.RenegotiateFreelyAsClient\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid TLS renegotiation level: %v\", t.Renegotiation)\n\t}\n\n\t// override for the server name used verify the TLS handshake\n\tcfg.ServerName = repl.ReplaceKnown(cfg.ServerName, \"\")\n\n\t// throw all security out the window\n\tcfg.InsecureSkipVerify = t.InsecureSkipVerify\n\n\t// only return a config if it's not empty\n\tif reflect.DeepEqual(cfg, new(tls.Config)) {\n\t\treturn nil, nil\n\t}\n\n\treturn cfg, nil\n}\n\n// The HTTPCertPool fetches the trusted root certificates from HTTP(S)\n// endpoints. The TLS connection properties can be customized, including custom","sourceCodeStart":599,"sourceCodeEnd":635,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/capools.go#L599-L635","documentation":"While building a tls.Config for a CA pool source, the configured `renegotiation` value did not match any of the allowed levels. Only \"never\" (or empty), \"once\", and \"freely\" map to tls.RenegotiateNever, tls.RenegotiateOnceAsClient, and tls.RenegotiateFreelyAsClient respectively; anything else is rejected.","triggerScenarios":"Setting `renegotiation <value>` on a trust_pool/tls config where value is e.g. \"always\", \"true\", \"Never\" (case matters), or a typo like \"freelly\".","commonSituations":"Porting configs from other servers that use different renegotiation vocabularies; case or spelling mistakes; assuming boolean-like values are accepted.","solutions":["Set the value to exactly one of: never, once, freely (or omit it — default is never).","Check for stray whitespace or case differences in the config value.","Run `caddy validate --config Caddyfile` to catch the typo before reload."],"exampleFix":"# before\ntrust_pool http https://ca.example.com/bundle.pem {\n  renegotiation always\n}\n\n# after\ntrust_pool http https://ca.example.com/bundle.pem {\n  renegotiation freely\n}","handlingStrategy":"validation","validationCode":"// in config generation, whitelist renegotiation values\nvar validRenegotiation = map[string]bool{\"\": true, \"never\": true, \"once\": true, \"freely\": true}\n\nfunc sanitizeRenegotiation(v string) (string, error) {\n\tif !validRenegotiation[v] {\n\t\treturn \"\", fmt.Errorf(\"invalid renegotiation %q: must be never, once, or freely\", v)\n\t}\n\treturn v, nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate config with `caddy validate` in CI to catch enum typos.","Omit renegotiation unless a broken peer actually requires it; default (never) is the secure setting.","Remember values are case-sensitive lowercase."],"tags":["caddy","caddytls","tls","renegotiation","configuration","validation"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}