slackhq/nebula · error

Empty configuration

Error message

Empty configuration

What it means

C.LoadString in config/config.go refuses to load an empty configuration string: if raw == "" it returns errors.New("Empty configuration") without calling parseRaw. It guards against accidentally reloading/starting with no config content at all.

Source

Thrown at config/config.go:66

	}

	if len(c.files) == 0 {
		return fmt.Errorf("no config files found at %s", path)
	}

	sort.Strings(c.files)

	err = c.parse()
	if err != nil {
		return err
	}

	return nil
}

func (c *C) LoadString(raw string) error {
	if raw == "" {
		return errors.New("Empty configuration")
	}
	return c.parseRaw([]byte(raw))
}

// RegisterReloadCallback stores a function to be called when a config reload is triggered. The functions registered
// here should decide if they need to make a change to the current process before making the change. HasChanged can be
// used to help decide if a change is necessary.
// These functions should return quickly or spawn their own go routine if they will take a while
func (c *C) RegisterReloadCallback(f func(*C)) {
	c.callbacks = append(c.callbacks, f)
}

// InitialLoad returns true if this is the first load of the config, and ReloadConfig has not been called yet.
func (c *C) InitialLoad() bool {
	return c.oldSettings == nil
}

// HasChanged checks if the underlying structure of the provided key has changed after a config reload. The value of

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Check the config source is non-empty before loading (stat/read validation).
  2. Fix the upstream source: restore the file, fix the Secret/ConfigMap, or correct the template that rendered empty output.
  3. In code, return a clearer wrapper error or skip reload when the raw string is empty.
  4. If an empty config is legitimate, use parseRaw/Load with a valid minimal document like '{}' instead of an empty string.

Example fix

// before
raw, _ := os.ReadFile(cfgPath)
err := c.LoadString(string(raw))

// after
raw, err := os.ReadFile(cfgPath)
if err != nil { return err }
if len(bytes.TrimSpace(raw)) == 0 { return fmt.Errorf("config file %s is empty", cfgPath) }
return c.LoadString(string(raw))
Defensive patterns

Strategy: validation

Validate before calling

raw, err := os.ReadFile(cfgPath)
if err != nil { return err }
if len(bytes.TrimSpace(raw)) == 0 {
    return fmt.Errorf("config %s is empty; refusing to load", cfgPath)
}
err = c.LoadString(string(raw))

Type guard

func isNonEmptyConfig(raw string) bool {
    return len(strings.TrimSpace(raw)) > 0
}

Try / catch

if err := c.LoadString(raw); err != nil {
    if err.Error() == "Empty configuration" {
        return fmt.Errorf("config source empty: check %s content/mount", cfgPath)
    }
    return err
}

Prevention

When it happens

Trigger: Calling LoadString("") directly, or indirectly when a file read yields empty content and callers pipe it into LoadString via ReloadConfigString, run, or newSimpleService.

Common situations: Config file exists but is zero bytes (truncated write, failed mount, empty k8s Secret/ConfigMap); template rendering produced nothing; reading a file before it was written.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/c93ccae4306e8bf8. Report an issue: GitHub.