# How to Debug Issues Encountered During CUPP Password Generation

> Learn to debug CUPP password generation problems. Verify your config, inspect data with print statements, and use the built in test suite to quickly find and fix errors.

- Repository: [Mebus/cupp](https://github.com/Mebus/cupp)
- Tags: how-to-guide
- Published: 2026-07-01

---

**To debug CUPP password generation issues, verify your [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) configuration integrity, check intermediate data structures by adding print statements after `read_config()` and `generate_wordlist_from_profile()`, and use the built-in test suite in [`test_cupp.py`](https://github.com/Mebus/cupp/blob/main/test_cupp.py) to isolate failures.**

CUPP (Common User Passwords Profiler) generates targeted wordlists through multi-stage processing defined in the Mebus/cupp repository. When password generation fails, produces empty files, or crashes unexpectedly, systematic debugging requires tracing data flow through configuration loading, profile collection, and wordlist synthesis. Understanding the specific function signatures and file locations in [`cupp.py`](https://github.com/Mebus/cupp/blob/main/cupp.py) enables rapid identification of root causes.

## Understanding CUPP's Password Generation Pipeline

CUPP builds password wordlists in five distinct stages. Debugging requires checking each boundary where data transforms from one structure to another.

### Configuration Loading

In [`cupp.py`](https://github.com/Mebus/cupp/blob/main/cupp.py), the `read_config()` function (lines L52-L74) parses [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) and populates the global `CONFIG` dictionary. If this stage fails, all subsequent operations lack necessary parameters for years, special characters, and leet transformations.

### Profile Collection

The `interactive()` function (lines L299-L376) prompts users for personal data and stores it in a `profile` dictionary. Input validation errors here—such as improperly formatted birthdates—cause downstream generation failures or crashes.

### Wordlist Synthesis and Filtering

The `generate_wordlist_from_profile()` function (lines L721-L806) expands the profile into combinatorial strings, adds optional special characters, random numbers, and leet transformations. Generated candidates are filtered by length bounds (`wcfrom`, `wcto`) at lines L986-L1000 before the final list is written to disk via `print_to_file()` (lines L19-L35).

## Common CUPP Password Generation Issues and Solutions

### Empty or Missing Output Files

When no file is created or the output file is empty, `read_config()` likely failed due to a missing [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) or malformed sections. Insert a temporary `print(CONFIG)` immediately after the function call at line 23, or run `python -c "import cupp; cupp.read_config('cupp.cfg'); print(cupp.CONFIG)"` to verify the dictionary populated correctly.

### KeyError on CONFIG Dictionary

A `KeyError` such as `CONFIG['global']` indicates required configuration sections (`years`, `specialchars`, etc.) are missing or contain syntax errors. Open [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) and confirm all required keys exist, comparing your file against the sample in the repository.

### Empty Wordlist During Concatenation

If `listic` is empty, concatenation loops are skipped entirely. This occurs when the source wordlist file passed to `-w` is empty or unreadable. Print the size of `listic` after reading (around line 84) and verify the file exists using `os.path.isfile`.

### Special Character Handling Issues

Duplicate or missing special characters result from `spechars1` not being set to `y` or an empty `chars` list in the configuration. Verify that `CONFIG['global']['chars']` contains the expected characters (default is `!@#$%^&*`) and that you answered the interactive prompt with `y`.

### Leet Mode Produces Unexpected Strings

Incorrect leet transformations stem from an incomplete or overwritten `LEET` mapping. Print `CONFIG['LEET']` after `read_config()` (line 84) and check that each entry matches the [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) file definitions.

### ValueError in Random Number Generation

When the random-number component raises a `ValueError`, the `numfrom`/`numto` values in the `nums` section are either non-integers or have `numfrom > numto`. Ensure these values are numeric and properly ordered.

### Profile Parsing Crashes

Program crashes during profile parsing typically occur when the birthdate string length is not exactly 8 characters. Validate input length or add a guard clause: `if len(profile['birthdate']) != 8: raise ValueError("Birthdate must be 8 digits")`.

## Step-by-Step Debugging Workflow

Follow this systematic approach to isolate failures in the Mebus/cupp codebase:

1. **Enable verbose prints** – Add `print("[DEBUG] <msg>", var)` at the start of each stage (config loading, profile creation, and each combination loop) to trace data flow.

2. **Use pdb** – Insert `import pdb; pdb.set_trace()` where you suspect the list becomes empty, such as after `komb_unique = {...}` near line 441, to inspect variable states interactively.

3. **Run unit tests selectively** – The repository ships with a comprehensive test suite ([`test_cupp.py`](https://github.com/Mebus/cupp/blob/main/test_cupp.py)). Execute the failing test with `pytest -k generate_wordlist_from_profile -vv` to get a detailed traceback.

4. **Mock inputs** – The tests already patch `builtins.input`. Extend this approach to reproduce the exact interaction that caused the failure (see `test_interactive` in [`test_cupp.py`](https://github.com/Mebus/cupp/blob/main/test_cupp.py#L9-L46).

5. **Check file system side-effects** – After each run, verify that expected files exist (`*.cupp.txt`, `alectodb-*.txt`, etc.) using `os.path.isfile` to confirm output stages executed.

## Practical Debugging Code Examples

Add debug dumps to key functions to expose internal state:

```python

# Example: add a debug dump of the configuration

def read_config(filename):
    # ... existing code ...

    print("[DEBUG] Loaded CONFIG:", CONFIG)   # <-- add this line

    # ...

```

Inspect the filtered list before writing to prevent empty output:

```python

# Example: inspect the length-filtered list before writing

def print_to_file(filename, unique_list_finished):
    print("[DEBUG] Final list size:", len(unique_list_finished))  # <-- add

    # ...

```

Run targeted tests to isolate specific functionality:

```bash

# Example: run a single test with verbose output

$ pytest -k test_generate_wordlist_from_profile -vv

```

Mock a problematic profile to test edge cases without manual input:

```python

# Mocking a problematic profile (e.g. missing birthdate digits)

from unittest.mock import patch
with patch("builtins.input", side_effect=[
    "John", "Doe", "jdoe", "1234", "", "", "", "", "", "", "", "", "y", "y", "y"
]):
    interactive()   # will hit the birthdate length check and raise an error

```

## Summary

- **Configuration integrity** is the most common root cause; verify [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) exists and contains all required sections (`global`, `years`, `specialchars`, `LEET`) before debugging other components.
- **Data validation** occurs at multiple boundaries; check `profile` dictionary contents after `interactive()` and `listic` contents before combination loops.
- **Line-specific debugging** targets [`cupp.py`](https://github.com/Mebus/cupp/blob/main/cupp.py#L52-L74) (config), L299-L376 (profile), and L721-L806 (generation) for most issues.
- **Test-driven isolation** using `pytest -k` against [`test_cupp.py`](https://github.com/Mebus/cupp/blob/main/test_cupp.py) provides faster feedback than manual interactive testing.
- **File system verification** confirms that `print_to_file()` actually receives non-empty lists filtered by `wcfrom` and `wcto` bounds.

## Frequently Asked Questions

### Why is my CUPP output file empty?

An empty output file typically indicates that `read_config()` failed to populate the global `CONFIG` dictionary, or the wordlist filtering at lines L986-L1000 removed all candidates based on length constraints (`wcfrom`/`wcto`). Verify the configuration loaded correctly and check the length bounds in [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) match your expected password lengths.

### How do I fix KeyError: 'global' in CUPP?

This error occurs when the [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) file is missing the `[global]` section or contains syntax errors that prevent Python's ConfigParser from reading it. Compare your local file against the repository's [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) sample to ensure all required sections (`[global]`, `[years]`, `[specialchars]`, `[nums]`, `[LEET]`) are present and properly formatted with key-value pairs.

### Why are special characters not appearing in generated passwords?

Special characters require two conditions: the `chars` key in [`cupp.cfg`](https://github.com/Mebus/cupp/blob/main/cupp.cfg) must contain your desired symbols (default: `!@#$%^&*`), and the interactive prompt for special characters must be answered with `y` to set `spechars1` to `y`. Check both `CONFIG['global']['chars']` and the profile's `spechars1` value during debugging.

### How can I test CUPP without entering interactive data every time?

Use the mocking pattern from [`test_cupp.py`](https://github.com/Mebus/cupp/blob/main/test_cupp.py#L9-L46) to patch `builtins.input` with a predefined list of responses. This allows you to programmatically test `interactive()` and `generate_wordlist_from_profile()` with specific edge cases, such as incomplete birthdates or unusual name combinations, without manual intervention.