shadow1ng/fscan · warning
i18n.Tr("service_not_identified", "Memcached")
Error message
i18n.Tr("service_not_identified", "Memcached") What it means
identifyService returns this error when the TCP connection succeeded but the 'version' probe did not receive a response containing 'VERSION' or 'memcached' (testBasicCommand returned false). The port is open, but fscan cannot confirm the service is actually memcached, so it reports 'service not identified: Memcached'.
Source
Thrown at plugins/services/memcached.go:143
}
}
defer func() { _ = conn.Close() }()
if p.testBasicCommand(conn, session.Config) {
banner := "Memcached"
session.LogSuccess(i18n.Tr("memcached_service", target, banner))
return &ScanResult{
Type: plugins.ResultTypeService,
Success: true,
Service: "memcached",
Banner: banner,
}
}
return &ScanResult{
Success: false,
Service: "memcached",
Error: fmt.Errorf("%s", i18n.Tr("service_not_identified", "Memcached")),
}
}
func init() {
RegisterPluginWithPorts("memcached", func() Plugin {
return NewMemcachedPlugin()
}, []int{11211, 11212, 11213})
}
View on GitHub (pinned to 95cc12e753)
Solutions
- Manually probe the port (printf 'version\r\n' | nc <host> 11211) to see the actual banner.
- Identify what service is really listening on the port (banner grabbing, ss/netstat on the target).
- If a proxy wraps memcached, scan the memcached host directly instead.
- Increase ModuleTimeout if slow responses cause the read deadline to expire.
- Accept the result as expected behavior for non-memcached services on memcached ports.
Example fix
// before
// plugin side: testBasicCommand only accepts "VERSION" or "memcached" substrings
// after
// caller side: treat 'service not identified' as inconclusive, not fatal
res := plugin.Scan(ctx, info, session)
if !res.Success && strings.Contains(fmt.Sprint(res.Error), "not identified") {
log.Printf("port open on %s but not memcached; run generic banner grab", target)
} Defensive patterns
Strategy: fallback
Validate before calling
func bannerIsMemcached(target string, timeout time.Duration) bool {
conn, err := net.DialTimeout("tcp", target, timeout)
if err != nil { return false }
defer conn.Close()
conn.SetDeadline(time.Now().Add(timeout))
conn.Write([]byte("version\r\n"))
buf := make([]byte, 1024)
n, err := conn.Read(buf)
return err == nil && (strings.Contains(string(buf[:n]), "VERSION") || strings.Contains(string(buf[:n]), "memcached"))
} Type guard
func isNotIdentified(r *services.ScanResult) bool {
return r != nil && !r.Success && r.Error != nil && strings.Contains(r.Error.Error(), "not identified")
} Try / catch
result := plugin.Scan(ctx, info, session)
if !result.Success && isNotIdentified(result) {
banner := genericBannerGrab(target, 3*time.Second)
log.Printf("port open on %s but not confirmed memcached; got banner: %q", target, banner)
} Prevention
- Grab a generic banner on open ports to identify what really listens there
- Don't assume any service on 11211 is memcached — honeypots and proxies are common
- Use generous read deadlines; first-response latency can exceed the default timeout
- Exclude non-memcached hosts from the memcached plugin's port list
When it happens
Trigger: Running the memcached plugin (DisableBrute mode or via Scan) against an open port 11211-11213 where the server responds to 'version\r\n' with unexpected data, an empty reply, a read timeout, or a write error.
Common situations: A different service (proxy, honeypot, custom daemon) bound to 11211; memcached behind a TLS wrapper or proxy that speaks first; memcached configured with a modified/limited protocol response; IDS/IPs that tarpit protocol probes.
Related errors
- service_not_identified
- Unsupport FastPathPDU type 0x%x
- Unknown FastPathPDU type 0x%x
- NODE_RDP_PROTOCOL_PDU_SEC_BAD_LICENSE_HEADER
- Not a valid license packet
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/8aef8dea94da264a.
Report an issue: GitHub.