Gotchas#
Known pitfalls and edge cases. If you hit a non-obvious problem, add it here.
Hashcat Output Routing#
- Hashcat
event_log_warningandevent_log_advicego to stdout, not stderr -- onlyevent_log_errorgoes to stderr. Hash parse errors are warnings, so they appear on stdout. --status-jsononly structures the periodic status display -- errors/warnings remain plain text regardless of output mode.- v7.x changed per-hash error prefix from
Hashfile '...'toHash parsing error in hashfile: '...'-- patterns must match both. - Machine-readable error format (
<file>:<line>:<hash>:<error>) uses colons as delimiters, but many hash types also contain colons. Regex uses non-greedy(.+?)for the file path capture.
Clippy / Linting#
unsafe_codeis forbidden -- nounsafeblocks allowed anywhere.unwrap_usedis denied -- use?withanyhow/thiserror, or handle the error explicitly.panicis denied -- usebail!or returnErrinstead.expect_usedis warned -- prefercontext()from anyhow.warnings = "deny"makes ALL warnings fatal, includingdead_codeandunfulfilled_lint_expectations--#[expect(dead_code)]on items that are transitively reachable will itself error.as_conversionsis warned -- use.try_into().unwrap_or(fallback)or.into()instead ofascasts.pattern_type_mismatchis warned -- usematch *errwhen matching on&Treferences, notmatch err.match_same_armsis warned -- merge match arms with identical bodies using|.missing_const_for_fnis warned -- addconstto pure functions that qualify.redundant_closureis warned -- use.when(is_retryable)not.when(|e| is_retryable(e)).expect_used,unwrap_used,panic,indexing_slicingare warned/denied in production but allowed in#[cfg(test)]modules and integration tests via module-level#[allow(...)].
File Downloads#
- Resources (wordlists, masklists, rulelists) can exceed 100 GB. All download pipelines stream to disk -- never buffer fully in memory.
- Use atomic writes (temp file +
fs::rename) for crash safety on large downloads.
Cross-Platform#
- Hashcat session file location varies by OS:
~/.local/share/hashcat/sessions/(Linux),~/.hashcat/sessions/(legacy), or next to the binary (Windows). - Symlinks require elevated privileges on Windows -- test helpers should skip symlink tests on Windows.
Pre-commit Hooks#
rustfmt,mdformat, andcargo-sorthooks auto-fix files on first run, causing the commit to fail. Re-stage modified files and retry.- PostToolUse hooks (cargo fmt, clippy) may restructure code after edits -- always re-read modified files before making dependent changes to avoid working against stale assumptions.
cargo-sorthook rev may auto-update in.pre-commit-config.yaml-- stage the updated config alongside your commit.cargo-machetedetects unused dependencies -- remove them before committing.
Dependency Version Constraints#
reqwest0.13 renamed featurerustls-tlstorustls-- userustlsin Cargo.toml features.sha20.11 changedfinalize()return type -- output no longer implementsLowerHex. Format bytes manually withwrite!(acc, "{byte:02x}").
Retry Classification Testing#
reqwest::Errorhas no public constructors -- testis_retryableby producing real errors. Timeouts use awiremock::MockServerwith a delayed response and a short client timeout. Connect errors use192.0.2.1:1(RFC 5737 TEST-NET-1, guaranteed unroutable) with a shortconnect_timeout. Non-transient request errors use an invalid URL scheme (e.g.,ht!tp://invalid).- Only
is_timeout()andis_connect()are retryable forApiError::Request;is_request()includes permanent builder/decode errors.
Exit Codes#
- Hashcat negative exit codes (e.g., -11) arrive as unsigned 8-bit on Unix (e.g., 245).
normalize_exit_codeinhashcat/exit_code.rsconverts 245-255 back to -11 through -1 before classification.