hyperledger/fabric · error

config ID illegal, cannot be empty

Error message

config ID illegal, cannot be empty

What it means

validateConfigID rejects configuration item IDs (group/policy/value keys) that do not conform to Fabric's naming rules. An empty string is immediately illegal because every config element must have a non-empty identifier. This prevents ambiguous config paths in the channel configuration tree.

Source

Thrown at common/configtx/validator.go:52

type ValidatorImpl struct {
	channelID   string
	sequence    uint64
	configMap   map[string]comparable
	configProto *cb.Config
	namespace   string
	pm          policies.Manager
}

// validateConfigID makes sure that the config element names (ie map key of
// ConfigGroup) comply with the following restrictions
//  1. Contain only ASCII alphanumerics, dots '.', dashes '-'
//  2. Are shorter than 250 characters.
//  3. Are not the strings "." or "..".
func validateConfigID(configID string) error {
	re, _ := regexp.Compile(configAllowedChars)
	// Length
	if len(configID) <= 0 {
		return errors.New("config ID illegal, cannot be empty")
	}
	if len(configID) > MaxLength {
		return errors.Errorf("config ID illegal, cannot be longer than %d", MaxLength)
	}
	// Illegal name
	if _, ok := illegalNames[configID]; ok {
		return errors.Errorf("name '%s' for config ID is not allowed", configID)
	}
	// Illegal characters
	matched := re.FindString(configID)
	if len(matched) != len(configID) {
		return errors.Errorf("config ID '%s' contains illegal characters", configID)
	}

	return nil
}

// ValidateChannelID makes sure that proposed channel IDs comply with the

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Set a non-empty ID for every config group, value, and policy in the update
  2. Validate all config keys with validateConfigID-style checks before submitting the update
  3. Fix the generating script/template so the ID variable is populated
  4. Use configtxlator to decode and inspect the update to find the offending empty key

Example fix

// before
group.Groups[""] = &cb.ConfigGroup{}
// after
if name == "" {
    return errors.New("config group name must not be empty")
}
group.Groups[name] = &cb.ConfigGroup{}
Defensive patterns

Strategy: validation

Validate before calling

if configID == "" {
    return errors.New("config ID must not be empty")
}

Type guard

func validConfigID(id string) bool {
    return id != "" && len(id) <= 250 &&
        id != "." && id != ".." &&
        strings.TrimLeft(id, "abcdefghijklmnopqrstuvwxyz0123456789.-") == ""
}

Try / catch

if err := validateName(id); err != nil {
    return fmt.Errorf("invalid config ID: %w", err)
}

Prevention

When it happens

Trigger: Building a ConfigUpdate whose config group/value/policy map key is the empty string; programmatically constructing config groups with an unset Name/ID field.

Common situations: Hand-writing config update JSON/YAML where a key was omitted; a script generating config from a template with an unfilled variable; merging config trees where an element lost its ID.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/67f3111368798199. Report an issue: GitHub.