diff --git a/kwant/continuum/discretizer.py b/kwant/continuum/discretizer.py
index cac7839927305da0b828a279033fddd85fbf5386..119a4c11063b8013a23561abbe96ec33f1102add 100644
--- a/kwant/continuum/discretizer.py
+++ b/kwant/continuum/discretizer.py
@@ -6,6 +6,7 @@
 # the file AUTHORS.rst at the top-level directory of this distribution and at
 # http://kwant-project.org/authors.
 
+from keyword import iskeyword
 from collections import defaultdict
 import itertools
 
@@ -598,6 +599,15 @@ def _builder_value(expr, coords, grid_spacing, onsite,
     # as arguments to the value function
     arg_names = set.union({s.name for s in const_symbols},
                                 {str(k.func) for k in map_func_calls})
+
+    # check if all argument names are valid python identifiers
+    for name in arg_names:
+        if not (name.isidentifier() and not iskeyword(name)):
+            raise ValueError("Invalid name in used symbols: {}\n"
+                             "Names of symbols used in Hamiltonian "
+                             "must be valid Python identifiers and "
+                             "may not be keywords".format(name))
+
     arg_names = ', '.join(sorted(arg_names))
 
     if (not arg_names) and (coords is None):
diff --git a/kwant/continuum/tests/test_discretizer.py b/kwant/continuum/tests/test_discretizer.py
index 98a5cec8361dc3300081d1e2eb498df2ed0e4b49..47efbe3ad7e05ab5fe7b17e0e39b7300301ded9e 100644
--- a/kwant/continuum/tests/test_discretizer.py
+++ b/kwant/continuum/tests/test_discretizer.py
@@ -509,3 +509,16 @@ def test_numeric_functions_with_parameter():
                         rhs = f_num
 
                     assert np.allclose(lhs, rhs)
+
+
+@pytest.mark.parametrize('name', [
+    '1',
+    '1a',
+    '-a',
+    '+a',
+    'while',
+    'for'
+])
+def test_check_symbol_names(name):
+    with pytest.raises(ValueError):
+        discretize(sympy.Symbol(name), 'x')