ORA-06502: Accented Names Broke Checkout (Buffer Too Small)
ORA-06502 character string buffer too small: a value doesn't fit its PL/SQL variable, often because VARCHAR2(n) means n bytes, not characters.
20+ years shipping high-throughput database systems. Notes here come from systems that actually shipped.
- ✓Basic SQL knowledge (SELECT, INSERT, UPDATE)
- ✓Access to an Oracle database (any version 11g+)
- ✓Ability to run SQL*Plus or SQL Developer
- A value is bigger than the variable it's assigned to. The ORA-06512 line under it points to the exact assignment.
- Check bytes as well as characters: VARCHAR2(30) is 30 bytes by default, so 'FranΓ§oise' needs more bytes than letters. Compare LENGTHB() with LENGTH().
- Fix: declare variables with %TYPE, or size them in characters (VARCHAR2(30 CHAR)). Truncate with SUBSTR only when losing data is acceptable.
- It does not roll back your transaction: only the failing statement fails.
Imagine you're moving houses and you've labeled a box 'Books β max 20 lbs'. You keep stuffing books in until the bottom rips out. ORA-06502 is the database equivalent: you declared a variable as VARCHAR2(10) β a box that holds 10 characters β and then tried to put a 15-character string into it. The database refuses to silently drop characters; it throws an error and stops your program. The fix is either get a bigger box or cut the item down to size.
ORA-06502 is a sizing bug that waits for the right data. Code compiles, passes tests with names like 'John Smith', and then fails in production on the first customer whose name is longer, or simply has accents. The error itself is easy to read once you know its forms. 'Character string buffer too small' means a string didn't fit. 'Number precision too large' means a number didn't. 'Character to number conversion error' means TO_NUMBER was given something that isn't a number. The ORA-06512 line under it tells you exactly where.
This guide covers each form, the byte-versus-character trap behind many production cases, how to find the failing line and value, and the declaration habits that stop it happening again.
What ORA-06502 Actually Means (And Why It's Not a Syntax Error)
ORA-06502 is a runtime error. The code compiles cleanly and fails only when a value that doesn't fit actually arrives. That's why it gets past code review and tests. Read the suffix: 'character string buffer too small' means a string was too long for its variable. 'Number precision too large' means a number exceeded NUMBER(p,s). 'Character to number conversion error' means TO_NUMBER, or an implicit conversion, got a non-numeric string. In plain SQL the same bad conversion raises ORA-01722 instead. PL/SQL never truncates silently. It raises the error instead. Only the failing statement fails: earlier work in the transaction is still pending, and your exception handling decides whether to roll back.
The Root Cause: Variable Sizing vs. Real Data
Every 'buffer too small' error comes down to one thing: the target is smaller than the value. The source can be a column, a concatenation, a function result or a parameter. Measure in the right unit. LENGTH() counts characters; LENGTHB() counts bytes. If a variable was declared without CHAR, compare its size with LENGTHB(). That's how a value that fits the column, sized in CHAR, can still overflow a variable sized in bytes. The habit that prevents most cases is %TYPE: the variable inherits the column's exact type, size and length semantics, and follows the column when it changes.
How to Find the Exact Line That Failed
The error stack already tells you where it failed. The ORA-06512 line under ORA-06502 names the package, procedure and line number of the failing assignment. Inside an exception handler, DBMS_UTILITY.FORMAT_ERROR_BACKTRACE gives you that same location as a string to log. SQLERRM gives you only the message. Log the location together with the value and its LENGTH and LENGTHB. With those three things, finding the bad row takes minutes instead of hours.
The Numeric Variant: When ORA-06502 Isn't About Strings
ORA-06502 isn't only about strings. 'Number precision too large' means a value exceeded NUMBER(p,s): NUMBER(5,2) holds at most 999.99. 'Character to number conversion error' means a string such as '12A' was converted to a number inside PL/SQL. Validate before converting. On 12.2 and later, use TO_NUMBER(x DEFAULT NULL ON CONVERSION ERROR) or VALIDATE_CONVERSION(x AS NUMBER), which handle decimals and signs correctly. A simple REGEXP_LIKE('^[0-9]+$') rejects '12.50' and '-3'.
The Fix: Enlarge, Truncate, or Use CLOB
Once you've found the failing assignment, there are three fixes. Enlarge the variable when you need the full value: declare it with %TYPE, or size it in CHAR. This is the right fix in most cases. Truncate with SUBSTR only when losing the end of the value is acceptable, such as a display label or a log line. Use SUBSTRB if the target is sized in bytes. Use a CLOB when the value has no practical upper bound, such as JSON or XML. In PL/SQL, VARCHAR2 can hold up to 32,767 bytes. In SQL columns the limit is 4,000 bytes, or 32,767 with MAX_STRING_SIZE = EXTENDED.
Preventing ORA-06502 in Production: Defensive Coding Patterns
The best fix is prevention. Here are the patterns I use in every PL/SQL procedure that handles external data.
First, always use %TYPE for variables that read from tables. This eliminates the entire class of 'column grew but variable didn't' bugs.
Second, validate input lengths before assignment. If you're accepting a parameter from an application, check its length against your variable size and either truncate or raise a meaningful error.
Third, add an exception handler that logs the offending value and its length. When ORA-06502 does happen, you'll know exactly which record caused it.
Fourth, test with real production data. If you only test with 'John Doe', you'll never catch the 'Bartholomew Montgomery-Fitzgerald' case.
When ORA-06502 Hits a Trigger: Special Considerations
Triggers often cause ORA-06502 because they copy values into audit tables or variables sized differently from the source. The error is not vague: the stack shows ORA-06502, then ORA-06512 at the trigger's name and line, then ORA-04088 'error during execution of trigger'. Go to that line in USER_SOURCE (TYPE = 'TRIGGER'). If you want to log the offending value from inside the trigger, the log insert must be in an autonomous transaction. Otherwise the failing statement's rollback removes the log row along with everything else.
The %TYPE and %ROWTYPE Advantage: Never Guess Sizes Again
The single best way to prevent ORA-06502 is to stop hardcoding variable sizes. Use %TYPE for individual columns and %ROWTYPE for entire rows. This makes your code resilient to schema changes and eliminates the most common cause of this error.
%TYPE inherits the exact data type and size from a table column or another variable. If the column is VARCHAR2(100), your variable is VARCHAR2(100). If someone later alters the column to VARCHAR2(200), your variable automatically becomes VARCHAR2(200) the next time the procedure is recompiled.
%ROWTYPE does the same for an entire row. Declare v_customer customers%ROWTYPE and you get a record with fields matching every column in the customers table. This is perfect for SELECT * INTO or for passing rows between procedures.
Real Production Debugging: A Step-by-Step Recovery
When ORA-06502 hits production, work through it in order. Step 1: take the full stack from the application log. The ORA-06512 lines give the object and line. Step 2: read that line in USER_SOURCE and identify the target variable and its declared size, including CHAR or BYTE. Step 3: find the data. Compare MAX(LENGTH(col)) and MAX(LENGTHB(col)) in the source with the variable's size. Step 4: fix the declaration (%TYPE or CHAR semantics), then test with the exact failing value.
Accented Names Broke Checkout
- VARCHAR2(n) is n bytes unless you say CHAR.
- Declare variables with %TYPE, and test with real-world names, not 'John Smith'.
LENGTH()) and MAX(LENGTHB()) of the source. 5. Use %TYPE or CHAR sizing.LENGTH() of every string column. 3. Compare to your variable declarations. 4. The column with the largest difference is the culprit. 5. Fix the variable size or add validation.SELECT line, text FROM user_source WHERE name = 'YOUR_PROC' AND line BETWEEN <n>-3 AND <n>+3 ORDER BY line;SELECT MAX(LENGTH(your_column)) FROM your_table;| File | Command / Code | Purpose |
|---|---|---|
| ora06502_demo.sql | DECLARE | What ORA-06502 Actually Means (And Why It's Not a Syntax Err |
| safe_variable_declaration.sql | DECLARE | The Root Cause |
| error_backtrace_logging.sql | CREATE OR REPLACE PROCEDURE process_order(p_order_id NUMBER) IS | How to Find the Exact Line That Failed |
| numeric_overflow_demo.sql | DECLARE | The Numeric Variant |
| fix_strategies.sql | DECLARE | The Fix |
| defensive_plsql.sql | CREATE OR REPLACE PROCEDURE add_customer(p_name IN VARCHAR2, p_email IN VARCHAR2... | Preventing ORA-06502 in Production |
| trigger_error_handling.sql | CREATE OR REPLACE PROCEDURE log_value_error(p_src VARCHAR2, p_len NUMBER, p_lenb... | When ORA-06502 Hits a Trigger |
| type_rowtype_demo.sql | DECLARE | The %TYPE and %ROWTYPE Advantage |
| production_debug_queries.sql | SELECT MAX(LENGTH(customer_name)) AS max_chars, | Real Production Debugging |
Key takeaways
LENGTHB(), not just LENGTH().Interview Questions on This Topic
How does PL/SQL handle string assignment when the source is longer than the target variable, and why does it throw ORA-06502 instead of truncating?
Frequently Asked Questions
20+ years shipping high-throughput database systems. Notes here come from systems that actually shipped.
That's PL/SQL. Mark it forged?
3 min read · try the examples if you haven't