#finance-ledger #ledger #beancount #accounting #double-entry

rustledger-validate

Beancount validation with 27 error codes for ledger correctness

24 releases (9 breaking)

Uses new Rust 2024

new 0.11.0 Apr 3, 2026
0.10.1 Mar 13, 2026
0.9.1 Feb 18, 2026

#11 in #double-entry

Download history 91/week @ 2026-01-16 83/week @ 2026-01-23 49/week @ 2026-01-30 20/week @ 2026-02-06 104/week @ 2026-02-13 52/week @ 2026-02-20 68/week @ 2026-02-27 50/week @ 2026-03-06 14/week @ 2026-03-13 36/week @ 2026-03-20 58/week @ 2026-03-27

163 downloads per month
Used in 5 crates

GPL-3.0-only

760KB
15K SLoC

Beancount validation rules.

This crate implements validation checks for beancount ledgers:

  • Account lifecycle (opened before use, not used after close)
  • Balance assertions
  • Transaction balancing
  • Currency constraints
  • Booking validation (lot matching, sufficient units)

Error Codes

All error codes follow the spec in spec/validation.md:

Code Description
E1001 Account not opened
E1002 Account already open
E1003 Account already closed
E1004 Account close with non-zero balance
E1005 Invalid account name
E2001 Balance assertion failed
E2002 Balance exceeds explicit tolerance
E2003 Pad without subsequent balance
E2004 Multiple pads for same balance
E3001 Transaction does not balance
E3002 Multiple missing amounts in transaction
E3003 Transaction has no postings
E3004 Transaction has single posting (warning)
E4001 No matching lot for reduction
E4002 Insufficient units in lot
E4003 Ambiguous lot match
E4004 Reduction would create negative inventory
E5001 Currency not declared
E5002 Currency not allowed in account
E6001 Duplicate metadata key
E6002 Invalid metadata value
E7001 Unknown option
E7002 Invalid option value
E7003 Duplicate option
E8001 Document file not found
E10001 Date out of order (info)
E10002 Entry dated in the future (warning)

rustledger-validate

Beancount validation with 27 error codes for ledger correctness.

Error Categories

Range Category
E1xxx Account errors (not opened, already closed, etc.)
E2xxx Balance/pad errors
E3xxx Transaction errors (unbalanced, no postings)
E4xxx Inventory/lot errors
E5xxx Currency errors
E6xxx Metadata errors
E7xxx Option errors
E8xxx Document errors
E10xxx Date warnings

Example

use rustledger_validate::{validate, validate_with_options, ValidationOptions};

// Simple validation
let errors = validate(&directives);

// Validation with options
let options = ValidationOptions::default();
let errors = validate_with_options(&directives, options);

for error in errors {
    eprintln!("{}: {}", error.code(), error.message());
}

Features

  • Parallel validation with rayon
  • Configurable error severity
  • Rich error messages with source locations

License

GPL-3.0

Dependencies

~11–24MB
~328K SLoC