ConverterError: Some ops are not supported by the native TFLite runtime (Select TF ops)
Your model uses TensorFlow operations that TensorFlow Lite's built-in set does not include. Enable Select TF ops in the converter — accepting a bigger binary — or rewrite the model to built-ins only.
Updated
The error
tensorflow.lite.python.convert_phase.ConverterError: <unknown>:0: error: 'tf.Erf' op is neither a custom op nor a flex op <unknown>:0: note: Error code: ERROR_NEEDS_FLEX_OPS Some ops are not supported by the native TFLite runtime, you can enable TF kernels fallback using TF Select. See instructions: https://www.tensorflow.org/lite/guide/ops_select TF Select ops: Erf
The named ops vary — Erf, RandomStandardNormal, string ops — the structure does not.
What it means
TensorFlow Lite runs models on phones and edge devices using a deliberately small set of built-in operators, chosen for size and speed. The converter walked your model's graph and found operations outside that set. It lists them (TF Select ops: Erf) and refuses, because the standard TFLite runtime on the device would not know how to execute them.
Why it happens
Full TensorFlow has thousands of ops; TFLite builds in a fraction. Anything slightly unusual — special math functions, certain layer configurations, string processing, some preprocessing baked into the model — falls outside. Keras models built from standard layers mostly convert cleanly; models with custom activations, TF-function preprocessing or research-flavoured layers hit this wall.
How to fix it
1. Enable Select TF ops — the documented escape hatch.
import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model("saved_model_dir")
converter.target_spec.supported_ops = [
tf.lite.OpsSet.TFLITE_BUILTINS, # prefer built-ins
tf.lite.OpsSet.SELECT_TF_OPS, # fall back to TF kernels for the rest
]
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)The listed ops now execute through bundled TensorFlow kernels ("Flex delegate"). The cost: the runtime on the device must include the Select-ops support, which adds meaningfully to app size, and Flex ops run slower than built-ins.
2. Ship the matching runtime on the device. The Python interpreter supports Flex ops out of the box, so desktop testing works immediately. For Android/iOS apps, add the select-ops dependency alongside the standard TFLite library (the tensorflow-lite-select-tf-ops artifact on Android, the corresponding pod on iOS) — without it, the app crashes at model load naming the same ops.
3. The leaner alternative: remove the offending ops from the model. For each named op, ask where it comes from and whether a built-in substitute exists — replacing an exotic activation with a standard one and retraining briefly, or moving preprocessing out of the model into app code. A built-ins-only model is smaller and faster on-device, which is the point of TFLite.
4. Re-examine whether the op list shrinks with a newer TensorFlow. The built-in set grows over releases; converting with a current TF sometimes clears ops an older converter flagged.
How to prevent it
Design for conversion from the start when mobile is the target: standard Keras layers, preprocessing outside the graph, and a conversion smoke-test in CI so a new layer that breaks convertibility fails the build the day it is added — not the week of release.
Related errors
- Exporting the operator to ONNX is not supported — the same class of problem in the ONNX world
- Could not load dynamic library libcudart (TensorFlow)
- CUDAExecutionProvider is not available