AssertionError in Gurobi.jl with OptimalityTarget = 1 on simple nonlinear model (Gurobi 13)

Hi all,

I’m getting an AssertionError when using Gurobi 13 through JuMP with a very small nonlinear model, but only when I set OptimalityTarget = 1.

Minimal working example:

using JuMP, Gurobi

m = Model(Gurobi.Optimizer)
set_optimizer_attribute(m, "OptimalityTarget", 1)

@variable(m, 0 <= x <= 10)
@objective(m, Min, (x - 4)^2 - sin(x))

optimize!(m)
Set parameter OptimalityTarget to value 1
Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (mac64[arm] - Darwin 25.1.0 25B78)

CPU model: Apple M4 Pro
Thread count: 14 physical cores, 14 logical processors, using up to 14 threads

Non-default parameters:
OptimalityTarget  1
NonConvex  2

Optimize a model with 0 rows, 3 columns and 0 nonzeros (Min)
Model fingerprint: 0x46697c78
Model has 1 linear objective coefficients
Model has 1 general nonlinear constraint (2 nonlinear terms)
Variable types: 3 continuous, 0 integer (0 binary)
Coefficient statistics:
  Matrix range     [0e+00, 0e+00]
  Objective range  [1e+00, 1e+00]
  Bounds range     [1e+01, 1e+01]
  RHS range        [0e+00, 0e+00]
  NLCon coe range  [8e+00, 2e+01]
Presolve time: 0.00s
Presolved: 0 rows, 3 columns, 0 nonzeros
Presolved model has 1 nonlinear constraint(s)

Solving NLP to local optimality

... (barrier iterations) ...

NL barrier solved model in 11 iterations and 0.00 seconds (0.00 work units)
First-order optimal solution
Solution objective 5.995500436724e-01

User-callback calls 130, time in user-callback 0.00 sec
ERROR: AssertionError: 1 <= valueP[] <= 17
Stacktrace:
  [1] _raw_status(model::Gurobi.Optimizer)
    @ Gurobi ~/.julia/packages/Gurobi/Wo3Rk/src/MOI_wrapper/MOI_wrapper.jl:2921
  [2] get
    @ ~/.julia/packages/Gurobi/Wo3Rk/src/MOI_wrapper/MOI_wrapper.jl:2932 [inlined]
  [3] get(model::Gurobi.Optimizer, attr::MathOptInterface.PrimalStatus)
    @ Gurobi ~/.julia/packages/Gurobi/Wo3Rk/src/MOI_wrapper/MOI_wrapper.jl:2944
  [4] optimize!(model::Gurobi.Optimizer)
    @ Gurobi ~/.julia/packages/Gurobi/Wo3Rk/src/MOI_wrapper/MOI_wrapper.jl:2828
  [5] optimize!
    @ ~/.julia/packages/MathOptInterface/tVdNJ/src/Bridges/bridge_optimizer.jl:367 [inlined]
  [6] optimize!
    @ ~/.julia/packages/MathOptInterface/tVdNJ/src/MathOptInterface.jl:122 [inlined]
  [7] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{…})
    @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/tVdNJ/src/Utilities/cachingoptimizer.jl:370
  [8] optimize!(model::Model; ignore_optimize_hook::Bool, _differentiation_backend::MathOptInterface.Nonlinear.SparseReverseMode, kwargs::@Kwargs{})
    @ JuMP ~/.julia/packages/JuMP/e83v9/src/optimizer_interface.jl:609
  [9] optimize!(model::Model)
    @ JuMP ~/.julia/packages/JuMP/e83v9/src/optimizer_interface.jl:560
 [10] top-level scope
    @ ex_nlp_Gurobi.jl:9

So Gurobi appears to solve the NLP to local optimality, but then Gurobi.jl crashes when querying the status (1 <= valueP <= 17 assertion).

If I remove the OptimalityTarget attribute, the same model runs fine:

using JuMP, Gurobi

m = Model(Gurobi.Optimizer)

@variable(m, 0 <= x <= 10)
@objective(m, Min, (x - 4)^2 - sin(x))

optimize!(m)

This gives a normal solve with:

Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (mac64[arm] - Darwin 25.1.0 25B78)

CPU model: Apple M4 Pro
Thread count: 14 physical cores, 14 logical processors, using up to 14 threads

Non-default parameters:
NonConvex  2

Optimize a model with 0 rows, 3 columns and 0 nonzeros (Min)
...
Optimal solution found (tolerance 1.00e-04)
Best objective 5.995492605723e-01, best bound 5.995370086158e-01, gap 0.0020%

User-callback calls 153, time in user-callback 0.00 sec

Is OptimalityTarget = 1 supposed to be supported for nonlinear models in the Gurobi–JuMP integration, or is this parameter only meaningful for certain problem classes?

We still need to update Gurobi.jl to reflect some of the changes in Gurobi 13. We had a problem accessing the Gurobi binaries so that’s the current blocker. I may not get a chance to look at this until next week, sorry.

Thanks for the quick reply and for the context. I’ll stick with the default/global setting for now.

I recalled that in the past we need to manually download the Gurobi solver in conjunction with installing Gurobi.jl. Looks like there was an update of the readme.md of Gurobi.jl.

Is the current situation (recommended procedure) that a new user only add the Gurobi.jl package from the julia side? Is the name of Gurobi_jll.jl aligned with the version of its underlying solver? It appears that Gurobi_jll.jl is still in version 12 currently:

  [2e9cd046] + Gurobi v1.8.0
  [c018c7e6] + Gurobi_jll v12.0.3

What if I’m an old user that already had installed the Gurobi12 solver. How should I update to 13? Do the same thing as if I were a new user? Will my license be automatically identified and still be effective in Gurobi13?

Should I now wait for the Gurobi_jll.jl to update to version 13? (I guess I should..)

Edit: Ok, I’ve downloaded a local Gurobi13 solver manually. It works, by doing some settings:

export LC_ALL=C
export GUROBI_HOME=/somedir/gurobi1300/linux64
export GUROBI_JL_USE_GUROBI_JLL="false"
export PATH=$GUROBI_HOME/bin:$PATH
export LD_LIBRARY_PATH=$GUROBI_HOME/lib:$LD_LIBRARY_PATH
export GRB_LICENSE_FILE=/somedir/gurobi1300/linux64/gurobi.lic

Edit2: I’ve just tried using the WLS license, which seems to be unusable to the async concurrent code I wrote under Gurobi12. Not knowing why, I acquired the NamedUser license as I used to… I feel somewhat strange about the new release… (maybe more tests is needed later on)

Gurobi_jll is not updated to v13 yet, because Gurobi changed how they distribute the upstream solver.

The issue is Update to Gurobi@13 · Issue #36 · jump-dev/Gurobi_jll.jl · GitHub