diff --git a/NEWS.rst b/NEWS.rst
index cbd90377..d4765e98 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -29,6 +29,8 @@ Bug Fixes
 * The parser no longer looks for shebangs in the REPL or `hy -c`.
 * `require` with relative module names should now work correctly with
   `hy -m`, as well as `hy2py`'s recursive mode.
+* `hy.models.Symbol` no longer allows constructing a symbol beginning
+  with `#`.
 
 New Features
 ------------------------------
diff --git a/hy/reader/hy_reader.py b/hy/reader/hy_reader.py
index 016b94e5..923b820e 100644
--- a/hy/reader/hy_reader.py
+++ b/hy/reader/hy_reader.py
@@ -98,7 +98,7 @@ def as_identifier(ident, reader=None):
     if reader is None:
         if (
             not ident
-            or ident[:1] == ":"
+            or ident[0] in ":#"
             or any(isnormalizedspace(c) for c in ident)
             or HyReader.NON_IDENT.intersection(ident)
         ):

diff --git a/tests/macros/test_macro_processor.py b/tests/macros/test_macro_processor.py
index 5fb31791..464dcca8 100644
--- a/tests/macros/test_macro_processor.py
+++ b/tests/macros/test_macro_processor.py
@@ -55,7 +55,7 @@ def test_macroexpand_nan():
 
 def test_macroexpand_source_data():
     # https://github.com/hylang/hy/issues/1944
-    ast = Expression([Symbol("#@"), String("a")])
+    ast = Expression([Symbol("when"), String("a")])
     ast.start_line = 3
     ast.start_column = 5
     bad = macroexpand_1(ast, "hy.core.macros")
diff --git a/tests/test_models.py b/tests/test_models.py
index c000e8bd..9ad85154 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -28,7 +28,8 @@ def test_symbol_or_keyword():
     for x in ("foo", "foo-bar", "foo_bar", "✈é😂⁂"):
         assert str(Symbol(x)) == x
         assert Keyword(x).name == x
-    for x in ("", ":foo", "5"):
+    for x in ("", ":foo", "5", "#foo"):
+        # https://github.com/hylang/hy/issues/2383
         with pytest.raises(ValueError):
             Symbol(x)
         assert Keyword(x).name == x

`(hy.models.Symbol "#foo")` should be an error
for the same reason as `(hy.models.Symbol "5")`: `#foo` doesn't parse as a symbol. It parses as a reader-macro call.
tests/test_models.py::test_symbol_or_keyword
tests/macros/test_macro_processor.py::test_preprocessor_simple tests/macros/test_macro_processor.py::test_preprocessor_expression tests/macros/test_macro_processor.py::test_preprocessor_exceptions tests/macros/test_macro_processor.py::test_macroexpand_nan tests/macros/test_macro_processor.py::test_macroexpand_source_data tests/test_models.py::test_wrap_int tests/test_models.py::test_wrap_tuple tests/test_models.py::test_wrap_nested_expr tests/test_models.py::test_replace_int tests/test_models.py::test_invalid_bracket_strings tests/test_models.py::test_replace_str tests/test_models.py::test_replace_tuple tests/test_models.py::test_list_add tests/test_models.py::test_list_slice tests/test_models.py::test_hydict_methods tests/test_models.py::test_set tests/test_models.py::test_equality tests/test_models.py::test_number_model_copy tests/test_models.py::test_compound_model_repr tests/test_models.py::test_recursive_model_detection