{"record":{"id":"7ac1bb3bf2d35252","repo":"docker/cli","slug":"unexpected-environment-variable-s","errorCode":null,"errorMessage":"unexpected environment variable '%s'","messagePattern":"unexpected environment variable '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/stack/loader.go","lineNumber":136,"sourceCode":"func buildEnvironment(env []string) (map[string]string, error) {\n\tresult := make(map[string]string, len(env))\n\tfor _, s := range env {\n\t\tif runtime.GOOS == \"windows\" && len(s) > 0 {\n\t\t\t// cmd.exe can have special environment variables which names start with \"=\".\n\t\t\t// They are only there for MS-DOS compatibility and we should ignore them.\n\t\t\t// See TestBuildEnvironment for examples.\n\t\t\t//\n\t\t\t// https://ss64.com/nt/syntax-variables.html\n\t\t\t// https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133\n\t\t\t// https://github.com/docker/cli/issues/4078\n\t\t\tif s[0] == '=' {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tk, v, ok := strings.Cut(s, \"=\")\n\t\tif !ok || k == \"\" {\n\t\t\treturn result, fmt.Errorf(\"unexpected environment variable '%s'\", s)\n\t\t}\n\t\t// value may be set, but empty if \"s\" is like \"K=\", not \"K\".\n\t\tresult[k] = v\n\t}\n\treturn result, nil\n}\n\nfunc loadConfigFiles(filenames []string, stdin io.Reader) ([]composetypes.ConfigFile, error) {\n\tconfigFiles := make([]composetypes.ConfigFile, 0, len(filenames))\n\n\tfor _, filename := range filenames {\n\t\tconfigFile, err := loadConfigFile(filename, stdin)\n\t\tif err != nil {\n\t\t\treturn configFiles, err\n\t\t}\n\t\tconfigFiles = append(configFiles, *configFile)\n\t}\n","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/stack/loader.go#L118-L154","documentation":"Raised by buildEnvironment when an entry from os.Environ() cannot be split into KEY=VALUE, i.e. it contains no '=' or has an empty key. The environment entries feed Compose variable interpolation, so a malformed entry would break interpolation silently.","triggerScenarios":"An environment variable string passed via os.Environ() (or a test fixture) that has no '=' separator or an empty key. strings.Cut at loader.go:134 returns ok=false for a string with no '=', or k==\"\" when the part before '=' is empty.","commonSituations":"Extremely rare in production shells (the OS normally enforces KEY=VALUE); seen in tests with malformed fixtures, on platforms injecting unusual env strings, or when an integration passes a crafted environ slice. Windows '='-prefixed MS-DOS vars are already filtered above this check.","solutions":["Identify the malformed environment string from the error's %s and remove or fix it.","Ensure any environ slice passed to the loader consists of KEY=VALUE entries with a non-empty KEY.","Sanitize/normalize environment entries before invoking the stack deploy path.","On Windows, confirm the malformed entry isn't an MS-DOS '=X' style var; those are filtered, but custom formats may slip through."],"exampleFix":"// before\nenviron := []string{\"FOO\", \"BAR=baz\"}  // \"FOO\" has no '='\n// after\nenviron := []string{\"FOO=\", \"BAR=baz\"}  // well-formed KEY=VALUE","handlingStrategy":"validation","validationCode":"// Sanitize an environ slice before passing to the loader\nfunc sanitizeEnviron(env []string) ([]string, error) {\n    out := make([]string, 0, len(env))\n    for _, s := range env {\n        k, v, ok := strings.Cut(s, \"=\")\n        if !ok || k == \"\" {\n            return nil, fmt.Errorf(\"malformed environment entry %q\", s)\n        }\n        out = append(out, k+\"=\"+v)\n    }\n    return out, nil\n}","typeGuard":"type EnvEntry struct{ Key, Value string }\n\nfunc parseEnvEntry(s string) (EnvEntry, error) {\n    k, v, ok := strings.Cut(s, \"=\")\n    if !ok || k == \"\" {\n        return EnvEntry{}, fmt.Errorf(\"invalid env %q\", s)\n    }\n    return EnvEntry{Key: k, Value: v}, nil\n}","tryCatchPattern":null,"preventionTips":["Filter out malformed entries from os.Environ() before composing.","Add tests covering entries with no '=' or empty keys.","On Windows, ignore MS-DOS '=X' style vars explicitly."],"tags":["docker","stack","compose","environment","validation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}