shadow1ng/fscan · error
webscan_poc_file_read_failed
webscan_poc_file_read_failed
Error message
webscan_poc_file_read_failed %s: %w
What it means
LoadPoc reads a POC from an embedded filesystem (embed.FS) at path "pocs/<fileName>" and wraps any ReadFile error under webscan_poc_file_read_failed. It fires when the embedded FS has no such entry, i.e. the file was not compiled into the binary or the name is wrong.
Source
Thrown at webscan/lib/Client.go:438
if err != nil {
return nil, fmt.Errorf("%s %s: %w", i18n.GetText("webscan_poc_parse_failed"), fileName, err)
}
// 转换为fscan内部格式
poc, err := universalPoc.ToFscanPoc()
if err != nil {
return nil, fmt.Errorf("%s %s: %w", i18n.GetText("webscan_poc_convert_failed"), fileName, err)
}
return poc, nil
}
// LoadPoc 从内嵌文件系统加载单个POC
func LoadPoc(fileName string, Pocs embed.FS) (*Poc, error) {
// 读取POC文件内容
yamlFile, err := Pocs.ReadFile("pocs/" + fileName)
if err != nil {
return nil, fmt.Errorf("%s %s: %w", i18n.GetText("webscan_poc_file_read_failed"), fileName, err)
}
// 解析YAML内容
return parsePocYAML(yamlFile, fileName)
}
// SelectPoc 根据名称关键字选择POC文件
func SelectPoc(Pocs embed.FS, pocname string) []string {
entries, err := Pocs.ReadDir("pocs")
if err != nil {
common.LogError(i18n.Tr("webscan_poc_dir_read_failed", err))
}
var foundFiles []string
// 查找匹配关键字的POC文件
for _, entry := range entries {
if strings.Contains(entry.Name(), pocname) {
foundFiles = append(foundFiles, entry.Name())View on GitHub (pinned to 95cc12e753)
Solutions
- Verify the file exists at pocs/<fileName> in the source tree and matches the //go:embed pocs/* pattern
- Rebuild the binary after adding new POC files (embed is compile-time)
- Pass only the bare filename (e.g. "tomcat.yml"), not "pocs/tomcat.yml" or an absolute path
- Use LoadPocbyPath instead if you need to load from the real filesystem
Example fix
// before (full path passed to embedded FS loader)
poc, err := LoadPoc("pocs/tomcat.yml", pocsFS)
// after (bare filename)
poc, err := LoadPoc("tomcat.yml", pocsFS)
// or for on-disk files:
poc, err := LoadPocbyPath("/path/to/tomcat.yml") Defensive patterns
Strategy: fallback
Validate before calling
if _, err := pocsFS.ReadFile("pocs/" + fileName); err != nil {
return fmt.Errorf("poc %q not embedded: %w", fileName, err)
} Try / catch
poc, err := LoadPoc(name, pocsFS)
if err != nil {
if _, statErr := os.Stat(filepath.Join("pocs", name)); statErr == nil {
poc, err = LoadPocbyPath(filepath.Join("pocs", name))
}
} Prevention
- Rebuild after adding POC files — embed.FS is compile-time only
- Pass bare filenames; LoadPoc prepends "pocs/" itself
- Match the //go:embed pattern exactly (watch case sensitivity)
When it happens
Trigger: LoadPoc(fileName, Pocs) where "pocs/"+fileName does not exist in the embed.FS — wrong filename, missing pocs/ prefix handling, or the POC file was added to disk but the binary wasn't rebuilt after the embed.
Common situations: Typo in POC filename or case mismatch, loading a POC that exists on disk but is not embedded (embed only includes files matching the //go:embed pattern at build time), calling LoadPoc with a full path instead of a bare filename.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- webscan_poc_convert_failed
- webscan_cel_env_not_initialized
- webscan_expression_compile_failed
- webscan_program_create_failed
- webscan_expression_eval_failed
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/09e996702868cfce.
Report an issue: GitHub.