Dev Docs Troubleshooting

Troubleshooting and Diagnostics

Audited against Netatalk d63155e13 on 2026-10-10. This describes the current source checkout; older releases may differ.

Start with the deployed build

Record the source revision, server/client versions, configuration path, execution mode, and selected storage/search backends. afpd -V reports compiled features; it does not prove that a particular module loaded or that every configured volume is usable.

Command-line parsing is in etc/afpd/afp_options.c. -F selects a config file and starts the daemon in the selected mode; there is no config-only syntax-check flag. Do not run a second server against live volumes simply to test a file.

Logging

include/atalk/logger.h defines levels and module types; libatalk/util/logger.c implements setuplog(), LOG() output, and reopening. Configuration is parsed early in afp_config_parse() so subsequent errors can be reported.

[Global]
log level = default:note, afpd:info, dsi:info, cnid:debug, uams:debug, sl:debug
log file = /var/log/netatalk.log

Adjust the destination for the installed service’s permissions. Without log file, the logger uses its default destination. Detailed debug output depends on the build’s debug setting. Available types include default, logger, cnid, afpd, dsi, atalkd, papd, uams, fce, ad, and sl.

Collect the first failure and nearby session messages, not just the final client error. Log-file rotation/reopen coverage is in test/integration/logreopen_test.sh.

Connection, signals, and reconnect

The AFP parent and DSI worker have different signal behavior. See AFP Daemon. Worker handlers set deferred flags and wake a self-pipe; the main loop executes shutdown, reload, tickle, debug, and reconnect actions.

afp_over_dsi() logs configured and actual TCP buffer sizes at session startup and transport disconnect reasons later. Check whether the session was running, sleeping, disconnected, or logged out before attributing a closure to the tickle timer.

Reconnect uses an opaque random token and matching UID, followed by fd transfer through the parent. PID reuse is not a reconnect credential. A CNID reset deliberately terminates affected sessions; a reconnect cannot make old IDs valid.

Send SIGINT only to the intended session worker for a diagnostic dump. The deferred debug action toggles detailed logging and produces cache dumps. Current paths are constructed in etc/afpd/dircache.c, libatalk/acl/cache.c, and the debug path in etc/afpd/afp_dsi.c; check its logged filename rather than assuming a fixed name.

AFP errors and CNID errors

AFP constants are in include/atalk/afp.h. A few common codes:

Error Interpretation
AFPERR_ACCESS (-5000) Access or permission failure
AFPERR_BADUAM (-5002) Requested authentication method unavailable
AFPERR_BADVERS (-5003) Unsupported AFP version
AFPERR_MISC (-5014) General/transient failure; inspect the subsystem log
AFPERR_NOOBJ (-5018), AFPERR_NOID (-5034) Object or ID unavailable; inspect path/CNID state
AFPERR_PARAM (-5019) Invalid request fields
AFPERR_NOTAUTH (-5023) Authentication failed or not established
AFPERR_NOOP (-5024) Command not available in the current dispatch state

A CNID BUSY, CORRUPT, or DB failure must not be reported as ordinary absence. Current callers use CNID_ERRNO_IS_BACKEND_FAILURE() and generally return retryable AFPERR_MISC. See CNID Error Contract.

Database and UUID failures

SQLite is mandatory/default; MySQL is optional. Berkeley DB files, daemon port 4700, and cnid_metad/cnid_dbd are not part of this checkout.

For SQLite, inspect the configured vol dbpath, volume name/UUID, path ownership and link checks, database/companion files, lock contention, and the first logged SQL error. The database is <volume name>.sqlite inside the resolved CNID directory and uses WAL. An empty UUID or an unwritable UUID registry can prevent opening.

The busy timeout is 3 seconds. Repeated contention is not proof of corruption. synchronous=NORMAL is the current implementation setting, not a guarantee that every last transaction survives a power failure.

dbd remains a maintenance utility. Use it without active clients and with permissions appropriate to the volume. -s suppresses filesystem modifications but is not a guarantee of zero database side effects. -f wipes identities; use it only when deliberately resetting the database and accepting possible alias/reference changes. -i invalidates metadata CNID hints. See Maintenance.

Cache diagnostics

Session-close logging in etc/afpd/dircache.c reports directory, AD, resource-fork, validation, and hint statistics. etc/afpd/pfd_cache.c reports parent-directory descriptor-cache statistics, and etc/afpd/idle_worker.c reports grant/cleanup work.

Compare cold/warm behavior and workload changes before interpreting a hit ratio. Inspect stale-on-use, validation, dropped-hint, and parent-path-repair counters when another service modifies files. Ordinary hints are best effort, not a lossless consistency guarantee.

Default validation frequency is 100; multi-protocol volumes default to per-access validation and resource-fork-cache exclusion. Explicit overrides remain active and can be accompanied by warnings. See Caching Architecture.

Missing volumes and permissions

The shared parser in libatalk/util/netatalk_conf.c performs volume construction and access filtering. Check the configured path as the authenticated user, valid users/invalid users, client host restrictions, read-only policy, and duplicate/nested-volume messages.

A section skipped for a nested path or failed UUID/storage initialization will not be fixed by changing TCP buffers. The controller’s LV_ALL volume list is also not evidence that a user is authorized to mount the volume.

ea = ad provides an AppleDouble EA fallback; it is not an error simply because the filesystem lacks native xattrs. Conversely, changing ea does not migrate existing metadata. Follow libatalk/adouble/ad_open.c and Shared Volumes.

Already-loaded volume options are retained during reload. Use a new session or restart when changes require a newly constructed volume. Single-user mode ignores SIGHUP entirely.

Authentication

Check both the compiled UAM and uam list/uam path, the Unix account and shell policy, and the module’s credential backend. PAM implementations use service netatalk; configuration is platform-specific.

SRP uses a verifier directory with numeric-UID filenames, ownership/mode/link validation, and exactly one correctly formatted account record. afppasswd defaults to SRP; -r selects Randnum. An old flat SRP file requires migration, and a configured directory without an enrolled verifier cannot authenticate the user.

LDAP support maps names/UUIDs for ACLs. Enabling it does not make AFP login authenticate passwords against LDAP. See Authentication.

Spotlight and discovery

Identify the configured spotlight backend first:

The default backend is cnid. Tracker-specific shell commands are not a general diagnostic for every backend, and the indexer’s private service context may differ from the interactive user’s session. Inspect sl logs and etc/spotlight.

Zeroconf registration is in etc/netatalk/afp_zeroconf.c. Verify the listener and access path separately from DNS-SD advertisements; discoverability does not prove a successful TCP login or volume mount.

Reproducing failures

Use test/README.md to select the relevant unit, integration, or AFP protocol test. Cache/path and database regressions are in test/afpd; client command cases are in test/testsuite. Recvfile framing/error tests are in test/afpd/subtests_recvfile.c. Include the triggering request, backend, storage mode, and concurrency in a bug report.

Footnotes

Generated from the Netatalk GitHub Wiki

Last updated 2026-10-21