{"record":{"id":"353b6c1eb57bb939","repo":"hyperledger/fabric","slug":"channel-id-illegal-cannot-be-empty-353b6c","errorCode":null,"errorMessage":"channel ID illegal, cannot be empty","messagePattern":"channel ID illegal, cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tx/endorser/parser.go","lineNumber":198,"sourceCode":"}\n\n// ValidateChannelID makes sure that proposed channel IDs comply with the\n// following restrictions:\n//  1. Contain only lower case ASCII alphanumerics, dots '.', and dashes '-'\n//  2. Are shorter than 250 characters.\n//  3. Start with a letter\n//\n// This is the intersection of the Kafka restrictions and CouchDB restrictions\n// with the following exception: '.' is converted to '_' in the CouchDB naming\n// This is to accommodate existing channel names with '.', especially in the\n// behave tests which rely on the dot notation for their sluggification.\n//\n// note: this function is a copy of the same in common/configtx/validator.go\nfunc ValidateChannelID(channelID string) error {\n\tre, _ := regexp.Compile(ChannelAllowedChars)\n\t// Length\n\tif len(channelID) <= 0 {\n\t\treturn errors.Errorf(\"channel ID illegal, cannot be empty\")\n\t}\n\tif len(channelID) > MaxLength {\n\t\treturn errors.Errorf(\"channel ID illegal, cannot be longer than %d\", MaxLength)\n\t}\n\n\t// Illegal characters\n\tmatched := re.FindString(channelID)\n\tif len(matched) != len(channelID) {\n\t\treturn errors.Errorf(\"'%s' contains illegal characters\", channelID)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":180,"sourceCodeEnd":212,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/tx/endorser/parser.go#L180-L212","documentation":"ValidateChannelID rejects a channel ID that is an empty string. Channel IDs are used in ledger paths, genesis blocks, and chaincode routing, so an empty one is structurally invalid. This check runs before the length and character checks.","triggerScenarios":"Passing \"\" as channelID to ValidateChannelID, or constructing a channel header with an empty ChannelId that later flows through validate() -> ValidateChannelID.","commonSituations":"Client code reading the channel name from an unset config/env variable; SDK createChannel calls with default struct values; copy-pasted code omitting the channel name argument.","solutions":["Supply a non-empty channel name (e.g. \"mychannel\") when creating the channel header or calling channel-creation APIs.","Validate channel name is set in your client config loader before submitting transactions.","Use a constant or config default for the channel name instead of an uninitialized variable."],"exampleFix":"// before\nchannelID := os.Getenv(\"CHANNEL\")\n// after\nchannelID := os.Getenv(\"CHANNEL\")\nif channelID == \"\" { channelID = \"mychannel\" }","handlingStrategy":"validation","validationCode":"if channelID == \"\" { return errors.New(\"channel ID must be non-empty\") }","typeGuard":"func validChannelID(id string) bool { return len(id) > 0 && len(id) <= 63 && regexp.MustCompile(`^[a-z][a-z0-9.-]*$`).MatchString(id) }","tryCatchPattern":null,"preventionTips":["Load channel names from config with required-value validation.","Define channel names as constants in shared code.","Run tx/endorser.ValidateChannelID client-side before any submission."],"tags":["fabric","channel-id","validation"],"backgroundTag":"invalid-channel-id","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}