Home β€Ί Database β€Ί ORA-06502: Accented Names Broke Checkout (Buffer Too Small)
Beginner 3 min · October 29, 2026
ORA-06502: PL/SQL Numeric or Value Error (Character String Buffer Too Small)

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.

N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Notes here come from systems that actually shipped.

Follow
✓ Production
production tested
October 29, 2026
last updated
2,089
articles · all by Naren
Before you start⏱ 25 min
  • ✓Basic SQL knowledge (SELECT, INSERT, UPDATE)
  • ✓Access to an Oracle database (any version 11g+)
  • ✓Ability to run SQL*Plus or SQL Developer
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
⚡Quick Answer
  • 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.
✦ Definition~90s read
What is ORA-06502?

ORA-06502 (PL/SQL: numeric or value error) is raised when a value doesn't fit the PL/SQL variable it's assigned to. The most common form is 'character string buffer too small': a string longer than the VARCHAR2 it's going into. Other forms include 'number precision too large' and 'character to number conversion error'.

β˜…
Imagine you're moving houses and you've labeled a box 'Books – max 20 lbs'.

A frequent hidden cause: VARCHAR2(30) usually means 30 bytes, and accented characters take two or more bytes each.

Plain-English First

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.

ora06502_demo.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- io.thecodeforge β€” Database tutorial
-- Demonstration of ORA-06502: character string buffer too small

DECLARE
  -- Declared a 10-character buffer
  customer_name VARCHAR2(10);
BEGIN
  -- This string is 17 characters long β€” will fail
  customer_name := 'Jonathan Smithson';
  DBMS_OUTPUT.PUT_LINE('Name: ' || customer_name);
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;
/
Output
Error: ORA-06502: PL/SQL: numeric or value error: character string buffer too small
⚠ Production Trap:
VARCHAR2(30) means 30 bytes under the default NLS_LENGTH_SEMANTICS = BYTE. In AL32UTF8, 'Γ©' takes 2 bytes and many Asian characters take 3. A 25-character name can overflow a VARCHAR2(30). Use VARCHAR2(30 CHAR) or %TYPE.

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.

safe_variable_declaration.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- io.thecodeforge β€” Database tutorial
-- Safe variable declaration using %TYPE

DECLARE
  -- Inherit the exact type and size from the table column
  v_customer_name customers.customer_name%TYPE;
  v_shipping_address customers.shipping_address%TYPE;
BEGIN
  SELECT customer_name, shipping_address
    INTO v_customer_name, v_shipping_address
    FROM customers
   WHERE customer_id = 1001;

  DBMS_OUTPUT.PUT_LINE('Name: ' || v_customer_name);
  DBMS_OUTPUT.PUT_LINE('Address: ' || v_shipping_address);
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE('Customer not found');
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;
/
Output
Name: Jonathan Smithson
Address: 123 Long Street Name, Suite 456, Springfield
Variable Sizing Decision Tree
IfReading from a table column
β†’
UseUse %TYPE to inherit exact size
IfConcatenating multiple strings
β†’
UseCalculate max possible length and declare accordingly, or use CLOB
IfReceiving data from external system
β†’
UseDeclare VARCHAR2(4000) or CLOB, then validate/truncate
IfBuilding a dynamic SQL string
β†’
UseUse VARCHAR2(32767) or CLOB for large statements

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.

error_backtrace_logging.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-- io.thecodeforge β€” Database tutorial
-- Logging the full error backtrace for ORA-06502

CREATE OR REPLACE PROCEDURE process_order(p_order_id NUMBER) IS
  v_customer_name VARCHAR2(10); -- intentionally too small for demo
BEGIN
  SELECT customer_name
    INTO v_customer_name
    FROM orders o
    JOIN customers c ON o.customer_id = c.customer_id
   WHERE o.order_id = p_order_id;

  DBMS_OUTPUT.PUT_LINE('Processing order for: ' || v_customer_name);
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
    DBMS_OUTPUT.PUT_LINE('Backtrace:');
    DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
    RAISE;
END;
/

-- Test with a long name
BEGIN
  process_order(1001);
EXCEPTION
  WHEN OTHERS THEN
    NULL; -- already logged
END;
/
Output
Error: ORA-06502: PL/SQL: numeric or value error: character string buffer too small
Backtrace:
ORA-06512: at "SCOTT.PROCESS_ORDER", line 7
ORA-06512: at line 2
πŸ’‘Senior Shortcut:
Always add DBMS_UTILITY.FORMAT_ERROR_BACKTRACE to your exception handlers. It gives you the exact package, procedure, and line number β€” no more guessing which assignment failed.

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'.

numeric_overflow_demo.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
-- io.thecodeforge β€” Database tutorial
-- Numeric variant of ORA-06502

DECLARE
  v_price NUMBER(5,2); -- max value 999.99
BEGIN
  -- This will fail: 1234.56 exceeds precision
  v_price := 1234.56;
  DBMS_OUTPUT.PUT_LINE('Price: ' || v_price);
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;
/

-- Safe conversion example
DECLARE
  v_input VARCHAR2(10) := '12A';
  v_number NUMBER;
BEGIN
  IF REGEXP_LIKE(v_input, '^[0-9]+$') THEN
    v_number := TO_NUMBER(v_input);
    DBMS_OUTPUT.PUT_LINE('Converted: ' || v_number);
  ELSE
    DBMS_OUTPUT.PUT_LINE('Invalid number: ' || v_input);
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;
/
Output
Error: ORA-06502: PL/SQL: numeric or value error: number precision too large
Invalid number: 12A

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.

fix_strategies.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-- io.thecodeforge β€” Database tutorial
-- Three strategies to fix ORA-06502

-- Strategy 1: Enlarge the variable using %TYPE
DECLARE
  v_name customers.customer_name%TYPE; -- inherits exact size
BEGIN
  SELECT customer_name INTO v_name FROM customers WHERE customer_id = 1001;
  DBMS_OUTPUT.PUT_LINE('Name: ' || v_name);
END;
/

-- Strategy 2: Truncate the source with SUBSTR
DECLARE
  v_short_name VARCHAR2(10);
  v_full_name VARCHAR2(100) := 'Jonathan Smithson';
BEGIN
  v_short_name := SUBSTR(v_full_name, 1, 10);
  DBMS_OUTPUT.PUT_LINE('Short name: ' || v_short_name);
END;
/

-- Strategy 3: Use CLOB for large text
DECLARE
  v_payload CLOB;
BEGIN
  v_payload := '{"order_id": 1001, "items": [...large JSON...]}';
  DBMS_OUTPUT.PUT_LINE('Payload length: ' || DBMS_LOB.GETLENGTH(v_payload));
END;
/
Output
Name: Jonathan Smithson
Short name: Jonathan S
Payload length: 42
Fix Strategy Decision Tree
IfSource is a table column and you need full value
β†’
UseUse %TYPE to inherit exact size
IfSource is a concatenation and you only need part
β†’
UseUse SUBSTR to truncate to target size
IfSource can exceed 4000 characters
β†’
UseUse CLOB and DBMS_LOB package
IfSource is external and unpredictable
β†’
UseDeclare VARCHAR2(4000) or CLOB, validate length before assignment

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.

defensive_plsql.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- io.thecodeforge β€” Database tutorial
-- Defensive pattern: sizes come from the table, errors carry context
CREATE OR REPLACE PROCEDURE add_customer(p_name IN VARCHAR2, p_email IN VARCHAR2) IS
  v_name  customers.full_name%TYPE;   -- size and CHAR/BYTE semantics from the column
  v_email customers.email%TYPE;
BEGIN
  v_name  := p_name;
  v_email := p_email;
  INSERT INTO customers (full_name, email) VALUES (v_name, v_email);
EXCEPTION
  WHEN VALUE_ERROR THEN   -- ORA-06502
    RAISE_APPLICATION_ERROR(-20010,
      'Value too large: name ' || LENGTH(p_name) || ' chars / ' || LENGTHB(p_name) || ' bytes, '
      || 'email ' || LENGTH(p_email) || ' chars', TRUE);
END;
/
Output
Procedure created.
⚠ Never Do This:
Don't catch VALUE_ERROR and carry on with a NULL or a truncated value. That turns a loud error into silent bad data. Add context (lengths, an ID) and re-raise, passing TRUE to RAISE_APPLICATION_ERROR to keep the original error stack.

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.

trigger_error_handling.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- io.thecodeforge β€” Database tutorial
-- Log the failing value in an AUTONOMOUS transaction, so it survives the rollback
CREATE OR REPLACE PROCEDURE log_value_error(p_src VARCHAR2, p_len NUMBER, p_lenb NUMBER) IS
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT INTO value_error_log (src, char_len, byte_len, logged_at)
  VALUES (p_src, p_len, p_lenb, SYSTIMESTAMP);
  COMMIT;
END;
/

CREATE OR REPLACE TRIGGER trg_customers_audit
AFTER INSERT OR UPDATE ON customers
FOR EACH ROW
BEGIN
  INSERT INTO customer_audit (customer_id, full_name, changed_at)
  VALUES (:NEW.customer_id, :NEW.full_name, SYSDATE);
EXCEPTION
  WHEN VALUE_ERROR THEN
    log_value_error('TRG_CUSTOMERS_AUDIT', LENGTH(:NEW.full_name), LENGTHB(:NEW.full_name));
    RAISE;
END;
/
Output
Procedure created.
Trigger created.

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.

type_rowtype_demo.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- io.thecodeforge β€” Database tutorial
-- Using %TYPE and %ROWTYPE to prevent ORA-06502

DECLARE
  -- %ROWTYPE: entire row matches table structure
  v_customer customers%ROWTYPE;
BEGIN
  SELECT * INTO v_customer FROM customers WHERE customer_id = 1001;

  DBMS_OUTPUT.PUT_LINE('Name: ' || v_customer.customer_name);
  DBMS_OUTPUT.PUT_LINE('Email: ' || v_customer.email);
  DBMS_OUTPUT.PUT_LINE('Address: ' || v_customer.shipping_address);
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE('Customer not found');
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;
/
Output
Name: Jonathan Smithson
Email: jonathan.smithson@example.com
Address: 123 Long Street Name, Suite 456, Springfield
πŸ’‘Senior Shortcut:
Use %TYPE for every variable that reads from a table. It's one extra word in the declaration and it eliminates an entire category of production bugs.

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.

production_debug_queries.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
-- io.thecodeforge β€” Database tutorial
-- Queries to diagnose ORA-06502 in production

-- 1. Find the longest values in a column
SELECT MAX(LENGTH(customer_name))  AS max_chars,
       MAX(LENGTHB(customer_name)) AS max_bytes,
       COUNT(*) AS total_rows
FROM customers;

-- 2. Find rows that exceed a specific length
SELECT customer_id, customer_name, LENGTH(customer_name) AS name_length
FROM customers
WHERE LENGTH(customer_name) > 50
ORDER BY name_length DESC;

-- 3. Check the declared size of a column
SELECT column_name, data_type, data_length, char_length, char_used
FROM user_tab_columns
WHERE table_name = 'CUSTOMERS'
  AND column_name = 'CUSTOMER_NAME';

-- 4. Find the source line that failed (if you have the line number)
SELECT line, text
FROM user_source
WHERE name = 'PROCESS_ORDER'
  AND type = 'PROCEDURE'
  AND line BETWEEN 1 AND 20
ORDER BY line;
Output
MAX_CHARS MAX_BYTES TOTAL_ROWS
--------- --------- ----------
29 33 10000
...
COLUMN_NAME DATA_TYPE DATA_LENGTH CHAR_LENGTH CHAR_USED
------------- --------- ----------- ----------- ---------
CUSTOMER_NAME VARCHAR2 120 30 C
● Production incidentPOST-MORTEMseverity: high

Accented Names Broke Checkout

Symptom
About 4% of checkouts for new EU customers failed with ORA-06502: character string buffer too small. Names like 'Françoise Hélène Dubois-Léger' failed; longer names without accents went through.
Assumption
The team assumed corrupt input from the new signup form, and spent a day adding input sanitising that changed nothing.
Root cause
The order package declared v_full_name VARCHAR2(30). With the database default NLS_LENGTH_SEMANTICS = BYTE, that means 30 bytes. The customers column was VARCHAR2(30 CHAR). 'Françoise Hélène Dubois-Léger' is 29 characters, but its four accented letters take two bytes each in AL32UTF8, so it's 33 bytes. It fit the column, but not the variable.
Fix
Declared the variable as customers.full_name%TYPE, so it always matches the column, and audited the package for other hardcoded VARCHAR2 sizes. A CI test now inserts multibyte names into every customer-facing field.
Key lesson
  • VARCHAR2(n) is n bytes unless you say CHAR.
  • Declare variables with %TYPE, and test with real-world names, not 'John Smith'.
Production debug guideSystematic recovery paths for the failure modes engineers actually hit.4 entries
Symptom · 01
ORA-06502: PL/SQL: numeric or value error: character string buffer too small in a package procedure
→
Fix
1. Take the full stack from the app log; the ORA-06512 line gives the object and line. 2. Read that line in USER_SOURCE. 3. Check the target's declared size, including CHAR or BYTE. 4. Compare with MAX(LENGTH()) and MAX(LENGTHB()) of the source. 5. Use %TYPE or CHAR sizing.
Symptom · 02
ORA-06502 only for certain customers/records, not all
→
Fix
1. Identify the failing record ID from application logs. 2. Query that record and check 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.
Symptom · 03
ORA-06502 with ORA-04088 (from a trigger)
→
Fix
1. The ORA-06512 line names the trigger and line. 2. Read it in USER_SOURCE with TYPE = 'TRIGGER'. 3. Check audit-table column sizes against the source columns. 4. If you log from the trigger, use an autonomous transaction.
Symptom · 04
ORA-06502 numeric or value error without 'character string buffer too small'
→
Fix
1. This is a numeric issue. Check for TO_NUMBER on non-numeric strings. 2. Add REGEXP_LIKE validation before conversion. 3. Check NUMBER(p,s) precision β€” if assigning 12345.67 to NUMBER(5,2), it fails. 4. Enlarge precision or validate range.
★ ORA-06502 Triage Cheat SheetFirst-response commands for when things go wrong β€” copy-paste ready.
`ORA-06502: PL/SQL: numeric or value error: character string buffer too small`−
Immediate action
Find the failing line and check the target variable size.
Commands
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;
Fix now
Change VARCHAR2(n) to %TYPE or enlarge n to match the source column.
`ORA-06502` only for specific records+
Immediate action
Find the longest values in the source column.
Commands
SELECT id, LENGTH(col) AS chars, LENGTHB(col) AS bytes FROM your_table ORDER BY bytes DESC FETCH FIRST 10 ROWS ONLY;
SELECT column_name, data_length FROM user_tab_columns WHERE table_name = 'YOUR_TABLE' AND column_name = 'YOUR_COLUMN';
Fix now
Enlarge the variable to match data_length, or truncate with SUBSTR.
ORA-06502 followed by ORA-04088+
Immediate action
It's a trigger; the ORA-06512 line names it.
Commands
SELECT line, text FROM user_source WHERE name = 'TRG_NAME' AND type = 'TRIGGER' ORDER BY line;
SELECT column_name, data_length, char_length, char_used FROM user_tab_columns WHERE table_name = 'AUDIT_TABLE';
Fix now
Size the audit column/variable to match the source (CHAR semantics or %TYPE).
`ORA-06502: numeric or value error` (no string suffix)+
Immediate action
Check for TO_NUMBER on non-numeric data.
Commands
SELECT col FROM your_table WHERE VALIDATE_CONVERSION(col AS NUMBER) = 0;
SELECT your_column, LENGTH(your_column) FROM your_table WHERE LENGTH(your_column) > 10;
Fix now
Use TO_NUMBER(col DEFAULT NULL ON CONVERSION ERROR) and handle the NULLs explicitly.
ApproachWhen to UseRisk
Hardcoded VARCHAR2(n)Never in production codeHigh β€” breaks when data grows
VARCHAR2(n CHAR)Variables not tied to a columnLow β€” sized in characters, safe for accents
%TYPEAny variable reading from a tableLow β€” inherits exact size
VARCHAR2(4000)External data with unknown max lengthMedium β€” still has a limit
CLOBText that can exceed 4000 charactersLow β€” but more complex to handle
SUBSTR truncationDisplay fields where full value isn't neededLow β€” but loses data
⚙ Quick Reference
9 commands from this guide
FileCommand / CodePurpose
ora06502_demo.sqlDECLAREWhat ORA-06502 Actually Means (And Why It's Not a Syntax Err
safe_variable_declaration.sqlDECLAREThe Root Cause
error_backtrace_logging.sqlCREATE OR REPLACE PROCEDURE process_order(p_order_id NUMBER) ISHow to Find the Exact Line That Failed
numeric_overflow_demo.sqlDECLAREThe Numeric Variant
fix_strategies.sqlDECLAREThe Fix
defensive_plsql.sqlCREATE OR REPLACE PROCEDURE add_customer(p_name IN VARCHAR2, p_email IN VARCHAR2...Preventing ORA-06502 in Production
trigger_error_handling.sqlCREATE OR REPLACE PROCEDURE log_value_error(p_src VARCHAR2, p_len NUMBER, p_lenb...When ORA-06502 Hits a Trigger
type_rowtype_demo.sqlDECLAREThe %TYPE and %ROWTYPE Advantage
production_debug_queries.sqlSELECT MAX(LENGTH(customer_name)) AS max_chars,Real Production Debugging

Key takeaways

1
ORA-06502 means a value didn't fit its PL/SQL variable. The ORA-06512 line under it points to the exact assignment.
2
VARCHAR2(n) is n bytes by default. Accented and non-Latin characters take more than one byte, so compare LENGTHB(), not just LENGTH().
3
Declare variables with %TYPE, or size them in CHAR, and truncate only on purpose with SUBSTR.
4
It doesn't roll back your transaction
only the failing statement fails.
5
The numeric forms come from NUMBER(p,s) overflow or bad conversions. Use DEFAULT NULL ON CONVERSION ERROR on 12.2+.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
How does PL/SQL handle string assignment when the source is longer than ...
Q02SENIOR
When would you choose VARCHAR2(4000) over CLOB for a PL/SQL variable, an...
Q03SENIOR
What happens when ORA-06502 occurs inside a trigger during a bulk INSERT...
Q04JUNIOR
What is the difference between %TYPE and %ROWTYPE, and when would you us...
Q05SENIOR
A production procedure started throwing ORA-06502 after a schema change....
Q06SENIOR
How would you design a PL/SQL data ingestion pipeline to handle unpredic...
Q01 of 06SENIOR

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?

ANSWER
PL/SQL never truncates silently. An oversized assignment raises ORA-06502 (VALUE_ERROR). SQL behaves the same way in its own terms: inserting a too-long value into a column raises ORA-12899 'value too large for column'. If you want truncation, you must ask for it with SUBSTR, or SUBSTRB for byte-sized targets.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
What does ORA-06502: PL/SQL: numeric or value error: character string buffer too small mean?
02
What's the difference between ORA-06502 and ORA-06512?
03
How do I find which line caused ORA-06502 in a PL/SQL package?
04
Can ORA-06502 happen with numbers instead of strings?
05
Why does ORA-06502 happen for a name that's shorter than the variable?
N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Notes here come from systems that actually shipped.

Follow
✓ Verified
production tested
October 29, 2026
last updated
2,089
articles · all by Naren
🔥

That's PL/SQL. Mark it forged?

3 min read · try the examples if you haven't

←
Previous
ORA-01000: Maximum Open Cursors Exceeded
30 / 30 · PL/SQL