diff --git a/modules/io/src/mol/pdb_writer.cc b/modules/io/src/mol/pdb_writer.cc
index 25faae932e3bcb292a26b56ba8628c59a68990b3..00778bc0ed64c7ca7a47a0ad4949d80d5218bf1b 100644
--- a/modules/io/src/mol/pdb_writer.cc
+++ b/modules/io/src/mol/pdb_writer.cc
@@ -141,7 +141,14 @@ void write_atom(std::ostream& ostr, FormattedLine& line,
       }
     }    
   }
-  line(22, 4)=fmt::LPaddedInt(res.GetNumber().GetNum());
+
+  int num = res.GetNumber().GetNum();
+  if(num < -999 || num > 9999) {
+    throw IOException("Residue number from " + res.GetQualifiedName() +
+                      " is out of range supported by the PDB format " 
+                      "(-999 to 9999)");
+  }
+  line(22, 4)=fmt::LPaddedInt(num);
   if (ins_code!=0) {
     line[26]=ins_code;
   }
diff --git a/modules/io/tests/test_io_pdb.cc b/modules/io/tests/test_io_pdb.cc
index ff4d3a8dbdfb70988274a0611802cc7413bded60..919092e5bcad7d88fc89bc5d3e5f862e394f31ce 100644
--- a/modules/io/tests/test_io_pdb.cc
+++ b/modules/io/tests/test_io_pdb.cc
@@ -781,6 +781,60 @@ BOOST_AUTO_TEST_CASE(res_name_too_long)
   BOOST_CHECK_THROW(writer.Write(ent), IOException);
 }
 
+BOOST_AUTO_TEST_CASE(res_num_too_low)
+{
+  std::stringstream out;
+  PDBWriter writer(out, IOProfile());
+  
+  mol::EntityHandle ent=mol::CreateEntity();
+  mol::XCSEditor edi=ent.EditXCS();
+  mol::ChainHandle ch = edi.InsertChain(String(1, 'A'));;
+  mol::ResidueHandle r = edi.AppendResidue(ch, "ARG");
+  edi.InsertAtom(r,"N",   geom::Vec3(26.861, 50.841, 38.803), "N");
+  edi.InsertAtom(r,"CA",  geom::Vec3(27.437, 49.969, 37.786), "C");
+  edi.InsertAtom(r,"C",   geom::Vec3(26.336, 48.959, 37.429), "C");
+  edi.InsertAtom(r,"O",   geom::Vec3(25.745, 48.313, 38.312), "O");
+  edi.InsertAtom(r,"CB",  geom::Vec3(28.653, 49.266, 38.349), "C");
+  edi.InsertAtom(r,"CG",  geom::Vec3(29.870, 50.188, 38.416), "C");
+  edi.InsertAtom(r,"CD",  geom::Vec3(31.033, 49.532, 39.173), "C");
+  edi.InsertAtom(r,"NE",  geom::Vec3(32.318, 50.244, 39.125), "N");
+  edi.InsertAtom(r,"CZ",  geom::Vec3(33.462, 49.750, 39.679), "C");
+  edi.InsertAtom(r,"NH1", geom::Vec3(33.522, 48.572, 40.308), "N");
+  edi.InsertAtom(r,"NH2", geom::Vec3(34.610, 50.427, 39.597), "N");
+
+  edi.SetResidueNumber(r, mol::ResNum(-999));
+  BOOST_CHECK_NO_THROW(writer.Write(ent));
+  edi.SetResidueNumber(r, mol::ResNum(-1000));
+  BOOST_CHECK_THROW(writer.Write(ent), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(res_num_too_high)
+{
+  std::stringstream out;
+  PDBWriter writer(out, IOProfile());
+  
+  mol::EntityHandle ent=mol::CreateEntity();
+  mol::XCSEditor edi=ent.EditXCS();
+  mol::ChainHandle ch = edi.InsertChain(String(1, 'A'));;
+  mol::ResidueHandle r = edi.AppendResidue(ch, "ARG");
+  edi.InsertAtom(r,"N",   geom::Vec3(26.861, 50.841, 38.803), "N");
+  edi.InsertAtom(r,"CA",  geom::Vec3(27.437, 49.969, 37.786), "C");
+  edi.InsertAtom(r,"C",   geom::Vec3(26.336, 48.959, 37.429), "C");
+  edi.InsertAtom(r,"O",   geom::Vec3(25.745, 48.313, 38.312), "O");
+  edi.InsertAtom(r,"CB",  geom::Vec3(28.653, 49.266, 38.349), "C");
+  edi.InsertAtom(r,"CG",  geom::Vec3(29.870, 50.188, 38.416), "C");
+  edi.InsertAtom(r,"CD",  geom::Vec3(31.033, 49.532, 39.173), "C");
+  edi.InsertAtom(r,"NE",  geom::Vec3(32.318, 50.244, 39.125), "N");
+  edi.InsertAtom(r,"CZ",  geom::Vec3(33.462, 49.750, 39.679), "C");
+  edi.InsertAtom(r,"NH1", geom::Vec3(33.522, 48.572, 40.308), "N");
+  edi.InsertAtom(r,"NH2", geom::Vec3(34.610, 50.427, 39.597), "N");
+
+  edi.SetResidueNumber(r, mol::ResNum(9999));
+  BOOST_CHECK_NO_THROW(writer.Write(ent));
+  edi.SetResidueNumber(r, mol::ResNum(10000));
+  BOOST_CHECK_THROW(writer.Write(ent), IOException);
+}
+
 
 BOOST_AUTO_TEST_CASE(res_name_mismatch_alt_loc)
 {