{"record":{"id":"7bee637052e9e7e8","repo":"docker/cli","slug":"invalid-storage-option","errorCode":null,"errorMessage":"invalid storage option","messagePattern":"invalid storage option","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/container/opts.go","lineNumber":987,"sourceCode":"\tfor _, opt := range securityOpts {\n\t\tif opt == \"systempaths=unconfined\" {\n\t\t\tmaskedPaths = []string{}\n\t\t\treadonlyPaths = []string{}\n\t\t} else {\n\t\t\tfiltered = append(filtered, opt)\n\t\t}\n\t}\n\n\treturn filtered, maskedPaths, readonlyPaths\n}\n\n// parses storage options per container into a map\nfunc parseStorageOpts(storageOpts []string) (map[string]string, error) {\n\tm := make(map[string]string)\n\tfor _, option := range storageOpts {\n\t\tk, v, ok := strings.Cut(option, \"=\")\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"invalid storage option\")\n\t\t}\n\t\tm[k] = v\n\t}\n\treturn m, nil\n}\n\n// parseDevice parses a device mapping string to a container.DeviceMapping struct\nfunc parseDevice(device, serverOS string) (container.DeviceMapping, error) {\n\tswitch serverOS {\n\tcase \"linux\":\n\t\treturn parseLinuxDevice(device)\n\tcase \"windows\":\n\t\t// Windows doesn't support mapping, so passing the given value as-is.\n\t\treturn container.DeviceMapping{PathOnHost: device}, nil\n\tdefault:\n\t\treturn container.DeviceMapping{}, fmt.Errorf(\"unknown server OS: %s\", serverOS)\n\t}\n}","sourceCodeStart":969,"sourceCodeEnd":1005,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/container/opts.go#L969-L1005","documentation":"Thrown by parseStorageOpts when a --storage-opt entry has no '=' separator and thus cannot be split into key=value. The function uses strings.Cut on '=' and errors if the delimiter is absent. Storage options must always be key=value pairs (e.g. size=10G).","triggerScenarios":"`docker run --storage-opt size10G ...` (missing '='), or `--storage-opt nosign`. Any storage option string failing strings.Cut(option, \"=\") triggers it.","commonSituations":"Typo omitting '='. Copying a value that lost its '=' through shell quoting/escaping. Using a bare flag name expecting a boolean. Misformatted compose storage_opt map entries passed as a single token.","solutions":["Rewrite the option as key=value: `--storage-opt size=10G`.","Check shell quoting around values containing '=' or special chars; quote the whole pair.","Refer to the driver's accepted keys (overlay2: size; devicemapper: dm.* keys) and ensure each is a pair."],"exampleFix":"// before\ndocker run --storage-opt size10G alpine\n\n// after\ndocker run --storage-opt size=10G alpine","handlingStrategy":"validation","validationCode":"func parseStorageOpt(s string) (string, string, error) {\n    k, v, ok := strings.Cut(s, \"=\")\n    if !ok {\n        return \"\", \"\", errors.New(\"invalid storage option\")\n    }\n    return k, v, nil\n}\n\nfor _, opt := range storageOpts {\n    if _, _, err := parseStorageOpt(opt); err != nil {\n        return err\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write storage options as key=value.","Shell-quote entire pairs to preserve '='.","Validate the option set against the storage driver's documented keys before invoking docker."],"tags":["storage","validation","cli-options","container"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}