{"record":{"id":"61cf1588e4d1bbc6","repo":"caddyserver/caddy","slug":"public-name-length-d-must-be-in-the-range-1-255","errorCode":null,"errorMessage":"public name length (%d) must be in the range 1-255","messagePattern":"public name length \\((.+?)\\) must be in the range 1-255","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/ech.go","lineNumber":1048,"sourceCode":"\t\t!content.Empty() {\n\t\treturn errInvalidLen\n\t}\n\techCfg.RawPublicName = string(rawPublicName)\n\n\treturn nil\n}\n\nvar errInvalidLen = errors.New(\"invalid length\")\n\n// marshalBinary writes this config to the cryptobyte builder. If there is an error,\n// it will occur before any writes have happened.\nfunc (echCfg echConfig) marshalBinary(b *cryptobyte.Builder) error {\n\tpk, err := echCfg.PublicKey.MarshalBinary()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif l := len(echCfg.RawPublicName); l == 0 || l > 255 {\n\t\treturn fmt.Errorf(\"public name length (%d) must be in the range 1-255\", l)\n\t}\n\n\tb.AddUint16(echCfg.Version)\n\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { // \"length\" field\n\t\tb.AddUint8(echCfg.ConfigID)\n\t\tb.AddUint16(uint16(echCfg.KEMID))\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tb.AddBytes(pk)\n\t\t})\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tfor _, cs := range echCfg.CipherSuites {\n\t\t\t\tb.AddUint16(uint16(cs.KDFID))\n\t\t\t\tb.AddUint16(uint16(cs.AEADID))\n\t\t\t}\n\t\t})\n\t\tb.AddUint8(uint8(min(len(echCfg.RawPublicName)+16, 255)))\n\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tb.AddBytes([]byte(echCfg.RawPublicName))","sourceCodeStart":1030,"sourceCodeEnd":1066,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/ech.go#L1030-L1066","documentation":"On the write path (marshalBinary), before emitting bytes the config is validated: RawPublicName — the DNS name clients see in the ECHConfigList — must be 1-255 bytes, matching the 1-byte length prefix format of ECH configs. Empty names or names over 255 bytes (including any length-prefix overhead considerations) abort serialization. This fires when creating/persisting a new ECH config with a bad public name.","triggerScenarios":"Creating an ECH config whose public_name is empty or a hostname longer than 255 bytes — misconfigured site label, programmatic address generation without length checks.","commonSituations":"Auto-generated ultra-long subdomains; configs where the public name field is omitted and defaults to empty; copy-paste of a full URL into a name field.","solutions":["Set a valid, non-empty public_name of at most 255 bytes for ECH.","Validate generated hostnames (DNS labels <=63 bytes, full name <=255) before feeding them into tls/ech config.","Use a short shared outer name (e.g. ech.example.com) as the public name."],"exampleFix":"// before\npublic_name := fmt.Sprintf(\"%s.%s.%s.example.com\", tenant, user, session) // may exceed 255\n\n// after\npublicName := \"tls-ech.example.com\" // fixed short outer name\nif len(publicName) == 0 || len(publicName) > 255 {\n    return fmt.Errorf(\"public name length invalid\")\n}","handlingStrategy":"validation","validationCode":"func validatePublicName(name string) error {\n    if l := len(name); l == 0 || l > 255 {\n        return fmt.Errorf(\"public name length (%d) must be in the range 1-255\", l)\n    }\n    for _, label := range strings.Split(name, \".\") {\n        if len(label) > 63 {\n            return fmt.Errorf(\"label too long: %s\", label)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cap generated hostnames at 255 bytes in templating/provisioning code.","Prefer a short dedicated public_name for ECH.","Add unit tests validating name bounds before config assembly."],"tags":["tls","ech","validation","dns"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}