shadowsocks/shadowsocks-rust · error

acl loading failed

Error message

acl loading failed

What it means

Thrown when a local config references an ACL file via `acl`, and AccessControl::load_from_file fails. The original error (IO, syntax, etc.) is wrapped in ErrorKind::Invalid with the file path and underlying error message.

Solutions

  1. Verify the path in `acl` exists and is readable (check with `ls -l` / try reading it)
  2. Fix the reported syntax error inside the ACL file shown in the wrapped error message
  3. Use an absolute path to avoid working-directory issues
  4. Remove the `acl` field if ACL filtering is not needed

Example fix

// before
{"acl": "./acl.txt"}  // file missing
// after
{"acl": "/etc/shadowsocks/acl.txt"}  // absolute, existing path
Defensive patterns

Strategy: try-catch

Validate before calling

let path = Path::new(acl_path);
assert!(path.exists(), "ACL file missing: {}", acl_path);
assert!(File::open(path).is_ok(), "ACL file unreadable: {}", acl_path);

Try / catch

match AccessControl::load_from_file(&acl_path) {
    Ok(acl) => acl,
    Err(e) => { log::error!("ACL {} failed: {e}", acl_path); return; }
}

Prevention

When it happens

Trigger: Config parsing with `acl` set to a path that does not exist, is unreadable (permissions), or contains lines the ACL parser rejects (bad rule syntax, invalid IP/CIDR entries, malformed regex lines).

Common situations: Typo in the ACL file path; file deleted or moved; running the service as a user without read permission; hand-edited ACL file with an invalid rule line; relative path resolved from an unexpected working directory.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09). Data as JSON: /api/errors/429f1a84e57fb0c1. Report an issue: GitHub.

Appendix: source

Thrown at crates/shadowsocks-service/src/config.rs:2087

                                        return Err(err);
                                    }
                                }
                            }
                            if let Some(p) = local.fake_dns_database_path {
                                local_config.fake_dns_database_path = Some(p.into());
                            }
                        }

                        let mut local_instance = LocalInstanceConfig {
                            config: local_config,
                            acl: None,
                        };

                        if let Some(acl_path) = local.acl {
                            let acl = match AccessControl::load_from_file(&acl_path) {
                                Ok(acl) => acl,
                                Err(err) => {
                                    let err = Error::new(
                                        ErrorKind::Invalid,
                                        "acl loading failed",
                                        Some(format!("file {acl_path}, error: {err}")),
                                    );
                                    return Err(err);
                                }
                            };
                            local_instance.acl = Some(acl);
                        }

                        nconfig.local.push(local_instance);
                    }
                }
            }
            ConfigType::Server | ConfigType::Manager => {
                // NOTE: IGNORED.
                // servers only uses `local_address` for binding outbound interfaces
                //

View on GitHub (pinned to 8eb0f0a65b)