{"record":{"id":"e235ac3d3de9f02a","repo":"henrygd/beszel","slug":"invalid-container-id","errorCode":null,"errorMessage":"invalid container id","messagePattern":"invalid container id","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/docker.go","lineNumber":794,"sourceCode":"\t}\n\treturn json.Unmarshal(dm.buf.Bytes(), d)\n}\n\n// Test docker / podman sockets and return if one exists\nfunc getDockerHost() string {\n\tscheme := \"unix://\"\n\tsocks := []string{\"/var/run/docker.sock\", fmt.Sprintf(\"/run/user/%v/podman/podman.sock\", os.Getuid())}\n\tfor _, sock := range socks {\n\t\tif _, err := os.Stat(sock); err == nil {\n\t\t\treturn scheme + sock\n\t\t}\n\t}\n\treturn scheme + socks[0]\n}\n\nfunc validateContainerID(containerID string) error {\n\tif !dockerContainerIDPattern.MatchString(containerID) {\n\t\treturn fmt.Errorf(\"invalid container id\")\n\t}\n\treturn nil\n}\n\nfunc buildDockerContainerEndpoint(containerID, action string, query url.Values) (string, error) {\n\tif err := validateContainerID(containerID); err != nil {\n\t\treturn \"\", err\n\t}\n\tu := &url.URL{\n\t\tScheme: \"http\",\n\t\tHost:   \"localhost\",\n\t\tPath:   fmt.Sprintf(\"/containers/%s/%s\", url.PathEscape(containerID), action),\n\t}\n\tif len(query) > 0 {\n\t\tu.RawQuery = query.Encode()\n\t}\n\treturn u.String(), nil\n}","sourceCodeStart":776,"sourceCodeEnd":812,"githubUrl":"https://github.com/henrygd/beszel/blob/b38fb7dafa60812cc22e6a84ce313e94f1ce0a32/agent/docker.go#L776-L812","documentation":"validateContainerID checks the container ID against dockerContainerIDPattern before it is interpolated into a Docker API URL. This error is thrown when the ID contains characters outside the allowed set (hex chars, length 12/64, or a name). It is a defensive guard against path traversal / endpoint injection via unsanitized container identifiers.","triggerScenarios":"buildDockerContainerEndpoint (or any caller passing through it) receives an empty string, a truncated/garbage ID, an ID with slashes, query characters, or whitespace — e.g. from a stale cache entry or untrusted API input.","commonSituations":"Frontend/API passes a user-supplied container name with invalid characters; internal cache holds an ID from a previous daemon instance; string slicing produced a malformed short ID.","solutions":["Ensure the container ID is the full 64-hex or 12-char short ID as returned by the daemon","Trim whitespace and reject empty values before calling container APIs","Regenerate/refresh cached container IDs instead of reusing old ones","If passing names, use only [a-zA-Z0-9][a-zA-Z0-9_.-]*"],"exampleFix":"// before\nendpoint, err := buildDockerContainerEndpoint(id, \"logs\", nil) // id from request param\n// after\nid = strings.TrimSpace(id)\nif !dockerContainerIDPattern.MatchString(id) {\n    return fmt.Errorf(\"bad container id from request\")\n}\nendpoint, err := buildDockerContainerEndpoint(id, \"logs\", nil)","handlingStrategy":"validation","validationCode":"var dockerContainerIDPattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_.-]*$`)\n\nfunc validContainerID(id string) bool {\n    id = strings.TrimSpace(id)\n    return len(id) >= 12 && dockerContainerIDPattern.MatchString(id)\n}","typeGuard":"func isValidContainerID(s string) bool {\n    return regexp.MustCompile(`^[a-f0-9]{12,64}$`).MatchString(s)\n}","tryCatchPattern":"if err := validateContainerID(id); err != nil {\n    http.Error(w, \"invalid container id\", http.StatusBadRequest)\n    return\n}","preventionTips":["Always use IDs straight from a fresh daemon list call","Never interpolate user input into Docker API paths without validation","Trim whitespace and reject empty IDs early"],"tags":["validation","security","docker"],"backgroundTag":"invalid-identifier-input","analyzedSha":"b38fb7dafa60812cc22e6a84ce313e94f1ce0a32","analyzedAt":"2026-08-31T15:10:10.149Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}