crowdsecurity/crowdsec · error
failed to parse api client credential configuration file '%s
Error message
failed to parse api client credential configuration file '%s': %w
What it means
This error is returned by csconfig's API client credential loader when the YAML file at CredentialsFilePath cannot be decoded into the Credentials struct. Because the decoder is created with KnownFields(true), any unknown or misspelled key in the YAML fails parsing, not just malformed YAML. The underlying yaml error is wrapped so the root cause (line number, offending field) is preserved.
Source
Thrown at pkg/csconfig/api.go:159
}
func (l *LocalApiClientCfg) Load() error {
patcher := csyaml.NewPatcher(l.CredentialsFilePath, ".local")
fcontent, err := patcher.MergedPatchContent()
if err != nil {
return err
}
configData := csstring.StrictExpand(string(fcontent), os.LookupEnv)
dec := yaml.NewDecoder(strings.NewReader(configData))
dec.KnownFields(true)
err = dec.Decode(&l.Credentials)
if err != nil {
if !errors.Is(err, io.EOF) {
return fmt.Errorf("failed to parse api client credential configuration file '%s': %w", l.CredentialsFilePath, err)
}
}
if l.Credentials == nil || l.Credentials.URL == "" {
return fmt.Errorf("no credentials or URL found in api client configuration '%s'", l.CredentialsFilePath)
}
if l.Credentials != nil && l.Credentials.URL != "" {
// don't append a trailing slash if the URL is a unix socket
if strings.HasPrefix(l.Credentials.URL, "http") && !strings.HasSuffix(l.Credentials.URL, "/") {
l.Credentials.URL += "/"
}
}
// is the configuration asking for client authentication via TLS?
credTLSClientAuth := l.Credentials.CertPath != "" || l.Credentials.KeyPath != ""
// is the configuration asking for TLS encryption and server authentication?View on GitHub (pinned to 909b515798)
Solutions
- Run `cscli lapi status` or inspect the file referenced in the error and fix the YAML syntax error reported in the wrapped message.
- Remove or correct unknown/misspelled keys — strict decoding rejects fields not present in the Credentials struct.
- Regenerate the credentials file with `cscli lapi register` or restore it from a known-good template.
- Convert tab characters to spaces; YAML forbids tabs for indentation.
Example fix
// before (invalid YAML / unknown key) url: http://127.0.0.1:8080 login: crowdsec password: secret api_urll: http://127.0.0.1:8080 # typo'd unknown key // after url: http://127.0.0.1:8080 login: crowdsec password: secret
Defensive patterns
Strategy: try-catch
Validate before calling
data, err := os.ReadFile(credPath)
if err != nil { return err }
var probe map[string]any
if err := yaml.Unmarshal(data, &probe); err != nil {
return fmt.Errorf("invalid YAML in %s: %w", credPath, err)
} Type guard
func hasKnownKeysOnly(data []byte, allowed map[string]bool) bool {
var m map[string]any
if yaml.Unmarshal(data, &m) != nil {
return false
}
for k := range m {
if !allowed[k] {
return false
}
}
return true
} Try / catch
if err := creds.Load(); err != nil {
if strings.Contains(err.Error(), "failed to parse api client credential configuration file") {
// fall back to regenerating: cscli lapi register
return fmt.Errorf("credentials file corrupt, re-run 'cscli lapi register': %w", err)
}
return err
} Prevention
- Only edit credentials files with cscli commands or validated templates.
- Use spaces, never tabs, in YAML indentation.
- After upgrading crowdsec, diff the credentials file against the new documented schema.
- Keep a known-good copy of the credentials file in config management.
When it happens
Trigger: Calling OnlineClientConfig.Load() (or any *APIClientConfig Load) where dec.Decode(&l.Credentials) fails: syntactically invalid YAML, wrong types (e.g. mapping a string where a struct is expected), or unknown keys due to KnownFields(true).
Common situations: Hand-edited /etc/crowdsec/local_api_credentials.yaml with a typo; lapi credentials written by an older/newer crowdsec version containing keys the current struct lacks; copy-pasting YAML with tabs instead of spaces; pasting enrollment output into the wrong file.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- cannot parse: %s
- failed to parse %s: %w
- failed to load parser config: %w
- failed to load postoverflow config: %w
- path must start with /
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/c80e4a3c33e020bf.
Report an issue: GitHub.