shadow1ng/fscan · warning
service_auth_failed: %d
Error message
service_auth_failed: %d
What it means
doNeo4jAuth probes the Neo4j HTTP endpoint (/user/neo4j) with basic-auth credentials. A 401 or 403 response means the credentials were rejected, so it returns an AuthResult with ErrorTypeAuth and the localized 'service_auth_failed' message plus the status code.
Source
Thrown at plugins/services/neo4j.go:112
Error: err,
}
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode == 200 {
return &AuthResult{
Success: true,
Conn: &neo4jConnWrapper{},
ErrorType: ErrorTypeUnknown,
Error: nil,
}
}
if resp.StatusCode == 401 || resp.StatusCode == 403 {
return &AuthResult{
Success: false,
ErrorType: ErrorTypeAuth,
Error: fmt.Errorf(i18n.GetText("service_auth_failed")+": %d", resp.StatusCode),
}
}
return &AuthResult{
Success: false,
ErrorType: ErrorTypeUnknown,
Error: fmt.Errorf(i18n.GetText("unknown_status_code")+": %d", resp.StatusCode),
}
}
// neo4jConnWrapper Neo4j连接包装器
type neo4jConnWrapper struct{}
func (w *neo4jConnWrapper) Close() error {
return nil
}
// classifyNeo4jErrorType Neo4j错误分类View on GitHub (pinned to 95cc12e753)
Solutions
- Treat 401 as a simple wrong-password result — continue with the next credential; nothing to fix in the client.
- For 403, verify manually whether the password is actually valid but the account lacks access to /user/neo4j (try a login endpoint instead).
- Check for WAF/proxy policies returning 401/403 independent of Neo4j auth, and bypass or allowlist the scanner.
- Confirm auth-related Neo4j settings (dbms.security.auth_enabled) if you expected unauthenticated access.
Example fix
// before
if resp.StatusCode == 401 || resp.StatusCode == 403 {
return authFailedWithStatus(resp.StatusCode)
}
// after
if resp.StatusCode == 401 {
return authFailedWithStatus(resp.StatusCode) // credentials rejected
}
if resp.StatusCode == 403 {
return &AuthResult{Success: false, ErrorType: ErrorTypePermission, Error: fmt.Errorf("forbidden: %d", resp.StatusCode)}
} Defensive patterns
Strategy: try-catch
Validate before calling
if resp.StatusCode == 401 || resp.StatusCode == 403 {
// record credential as rejected; do not retry the same pair
} Try / catch
res := doNeo4jAuth(ctx, info, cred, session)
if res.ErrorType == ErrorTypeAuth {
// move on to the next credential; check server logs if 403 persists
} Prevention
- Expect 401 as the normal rejection signal during brute force.
- Investigate persistent 403s separately: valid password but insufficient privileges.
- Rule out WAF/proxy 401/403 responses that are not Neo4j auth failures.
- Confirm dbms.security.auth_enabled matches the expected access model.
When it happens
Trigger: Any GET to http://<target>/user/neo4j with the candidate Credential's basic-auth that the server answers with HTTP 401 (bad user/pass) or 403 (authenticated but forbidden).
Common situations: Neo4j instances where auth is enabled and the guessed password is wrong (expected during scanning); 403 returned because the account lacks permissions to the /user endpoint even with a valid password; a reverse proxy in front returning 401/403 for its own reasons (IP blocklist, WAF).
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- oracle authentication failed
- oracle advanced authentication negotiation failed
- oracle authentication protocol internal error
- oracle session key should be either 64 or 96 bytes long
- NLA auth failed: error code %d (0x%X)
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/76c5ab1440ef0f45.
Report an issue: GitHub.