crowdsecurity/crowdsec · error

no credentials or URL found in api client configuration '%s'

Error message

no credentials or URL found in api client configuration '%s'

What it means

After successfully decoding the credentials YAML, the loader validates that the resulting Credentials object exists and that its URL field is non-empty. This error means the file parsed cleanly as YAML but contains no usable client configuration — typically an empty file, a file with only comments, or a document missing the required `url` key. It guards against silently proceeding with a zero-value client config.

Source

Thrown at pkg/csconfig/api.go:164

	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?
	credTLS := credTLSClientAuth || l.Credentials.CACertPath != ""

	credSocket := strings.HasPrefix(l.Credentials.URL, "/")

	if credTLS && credSocket {

View on GitHub (pinned to 909b515798)

Solutions

  1. Add the `url:` key pointing to the Local API, e.g. `url: http://127.0.0.1:8080`.
  2. If the file is empty, regenerate it: `cscli lapi register -u <LAPI url>` or restore from backup.
  3. Verify you are editing the file actually referenced (the path in the error message), not another config copy.
  4. Check file permissions/readability if a volume mount unexpectedly yielded an empty file.

Example fix

# before (empty or missing url)
login: crowdsec
password: secret
# after
url: http://127.0.0.1:8080/
login: crowdsec
password: secret
Defensive patterns

Strategy: validation

Validate before calling

cfg, err := yaml.Marshal(map[string]string{})
_ = cfg
data, _ := os.ReadFile(credPath)
var probe struct{ URL string `yaml:"url"` }
if err := yaml.Unmarshal(data, &probe); err != nil || probe.URL == "" {
    return fmt.Errorf("%s has no 'url' set", credPath)
}

Type guard

func hasURL(m map[string]any) bool {
    v, ok := m["url"]
    s, isStr := v.(string)
    return ok && isStr && strings.TrimSpace(s) != ""
}

Try / catch

if err := creds.Load(); err != nil {
    if strings.Contains(err.Error(), "no credentials or URL found") {
        return fmt.Errorf("credentials file empty or missing url; run 'cscli lapi register': %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Load() completes dec.Decode without error but l.Credentials == nil (empty/whitespace-only file, EOF document) or l.Credentials.URL == "" (file has login/password but no url key).

Common situations: credentials file created with `touch` but never populated; file truncated by a failed `cscli lapi register`; user deleted the url line while keeping login/password; mounted empty ConfigMap/volume in Kubernetes.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/e406137ea70e8d0d. Report an issue: GitHub.