unslothai/unsloth · error · NativePathLeaseError
Native path grant contains invalid characters.
Error message
Native path grant contains invalid characters.
What it means
One of the grant's free-text payload fields (canonical_path, nonce, token_id_hash, display_label) contains a NUL byte (\x00). The backend refuses NUL bytes because they cannot round-trip through C-based filesystem and OS APIs and are a classic payload-injection vector. Any presence means the signed payload itself was malformed at signing time. This check runs on optional fields too (only absent fields are skipped).
Source
Thrown at studio/backend/utils/native_path_leases.py:340
if payload["operation"] != operation:
raise NativePathLeaseError("Native path grant operation is invalid.")
if expected_kind and payload["path_kind"] != expected_kind:
raise NativePathLeaseError("Native path grant kind is invalid.")
now_ms = int(time.time() * 1000)
issued_at_ms = _required_int(payload, "issued_at_ms")
expires_at_ms = _required_int(payload, "expires_at_ms")
if issued_at_ms >= expires_at_ms:
raise NativePathLeaseError("Native path grant timestamps are inconsistent.")
if expires_at_ms <= now_ms:
raise NativePathLeaseError("Native path grant has expired.")
if issued_at_ms > now_ms + 30_000:
raise NativePathLeaseError("Native path grant issue time is invalid.")
for key in ("canonical_path", "nonce", "token_id_hash", "display_label"):
raw = payload.get(key)
if raw is None:
continue
if "\x00" in str(raw):
raise NativePathLeaseError("Native path grant contains invalid characters.")
def _validate_current_stat(
grant: NativePathGrant, identity_options: tuple[tuple[int, int], ...]
) -> tuple[int, int] | None:
try:
st = os.lstat(grant.canonical_path)
except OSError as exc:
raise NativePathLeaseError("Native path is no longer accessible.") from exc
if _stat_module.S_ISLNK(st.st_mode):
raise NativePathLeaseError("Native path is no longer a regular file.")
if grant.path_type == "file":
if not _stat_module.S_ISREG(st.st_mode):
raise NativePathLeaseError("Native path is no longer a regular file.")
elif grant.path_type == "directory":
if not _stat_module.S_ISDIR(st.st_mode):
raise NativePathLeaseError("Native path is no longer a directory.")
else:View on GitHub (pinned to 203007d190)
Solutions
- Decode the grant payload and locate the offending field: python -c "import base64,json;print(json.loads(base64.urlsafe_b64decode(lease.split('.')[0]+'==')))" and inspect for \x00.
- Fix the signer to strip/reject NUL bytes before building the JSON payload.
- Regenerate the grant; the backend cannot sanitize a signed payload (any edit breaks the HMAC).
- Add a unit test on the signer asserting no control characters in the four string fields.
Example fix
// before (Rust signer)
let nonce = bytes_with_nul.to_vec(); // embedded \x00 leaks into JSON
// after
let nonce = String::from_utf8(bytes)?.replace('\0', "");
assert!(!nonce.contains('\0')); Defensive patterns
Strategy: validation
Validate before calling
import base64, json
def grant_strings_clean(lease: str) -> bool:
payload = json.loads(base64.urlsafe_b64decode(lease.split('.')[0] + '=='))
return all(
'\x00' not in str(payload.get(k, ''))
for k in ('canonical_path', 'nonce', 'token_id_hash', 'display_label')
) Try / catch
try:
grant = verify_native_path_lease(lease, operation='read')
except NativePathLeaseError as exc:
if 'invalid characters' in str(exc):
lease = request_fresh_grant() # signed payload is corrupt at source
grant = verify_native_path_lease(lease, operation='read')
else:
raise Prevention
- Sanitize signer inputs: reject control characters before building the payload.
- Build payloads with a real JSON serializer, never string concatenation.
- Fuzz-test the signer's path and nonce fields for byte-level cleanliness.
When it happens
Trigger: verify_native_path_lease() with a payload where any of canonical_path/nonce/token_id_hash/display_label contains \x00. Produced by a signer bug that embeds raw bytes instead of UTF-8 strings, or by a hand-crafted signed payload used in tests containing embedded NULs.
Common situations: Rust signer writing a fixed-size buffer or a length-prefixed value into a JSON string without trimming; test fixtures generated with struct.pack or bytes concatenation; fuzzing pipelines feeding arbitrary bytes into the grant builder.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Native path contains invalid characters.
- Provider base URL contains invalid characters.
- A reference was sent empty.
- Native path grant timestamps are inconsistent.
- Native path grant issue time is invalid.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/a7b16bbc7c0107e4.
Report an issue: GitHub.