diff --git a/app/network/forms.py b/app/network/forms.py
index 268bbb3de3319205f1ecc061ac252b603bf961a1..b5abe3612fb04d1e09cb718d86f92f2cab9688a5 100644
--- a/app/network/forms.py
+++ b/app/network/forms.py
@@ -15,7 +15,7 @@ from wtforms import (SelectField, StringField, TextAreaField, IntegerField,
                      SelectMultipleField, BooleanField, validators)
 from ..helpers import CSEntryForm
 from ..validators import (Unique, RegexpList, IPNetwork, HOST_NAME_RE,
-                          VLAN_NAME_RE, MAC_ADDRESS_RE)
+                          VLAN_NAME_RE, MAC_ADDRESS_RE, CNAME_RE, CNAME_LEN_RE)
 from .. import utils, models
 
 
@@ -159,9 +159,10 @@ class InterfaceForm(CSEntryForm):
                     validators.Regexp(MAC_ADDRESS_RE, message='Invalid MAC address')])
     cnames_string = StringField(
         'Cnames',
-        description='space separated list of cnames (must be 2-20 characters long and contain only letters, numbers and dash)',
+        description='space separated list of cnames (fully-qualified domain name without the trailing dot)',
         validators=[validators.Optional(),
-                    RegexpList(HOST_NAME_RE)])
+                    RegexpList(CNAME_LEN_RE),
+                    RegexpList(CNAME_RE)])
     tags = SelectMultipleField('Tags', coerce=utils.coerce_to_str_or_none,
                                validators=[validate_tags])
 
diff --git a/app/validators.py b/app/validators.py
index 6c8ae870c02983efb7d2d7c6421fb019b442c439..0ff11b9c7cf9f6ad65939cb8b16db7c643189868 100644
--- a/app/validators.py
+++ b/app/validators.py
@@ -16,6 +16,8 @@ from wtforms import ValidationError
 
 ICS_ID_RE = re.compile('[A-Z]{3}[0-9]{3}')
 HOST_NAME_RE = re.compile('^[a-z0-9\-]{2,20}$')
+CNAME_LEN_RE = re.compile('^[a-z0-9\.\-]{2,252}$')
+CNAME_RE = re.compile('^((?!-)[a-z0-9\-]{1,62}\.)+[a-z]{1,62}$')
 VLAN_NAME_RE = re.compile('^[A-Za-z0-9\-]{3,25}$')
 MAC_ADDRESS_RE = re.compile('^(?:[0-9a-fA-F]{2}[:-]?){5}[0-9a-fA-F]{2}$')
 
diff --git a/tests/unit/test_validators.py b/tests/unit/test_validators.py
new file mode 100644
index 0000000000000000000000000000000000000000..447eed86fcd50c18c18fd4d964314acf313f92dc
--- /dev/null
+++ b/tests/unit/test_validators.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+"""
+tests.unit.test_validators
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This module defines validators tests.
+
+:copyright: (c) 2018 European Spallation Source ERIC
+:license: BSD 2-Clause, see LICENSE for more details.
+
+"""
+import pytest
+from app import validators
+
+
+@pytest.mark.parametrize('name', [
+    'a.se',
+    'myhost.esss.lu.se',
+    'myhost.tn.esss.lu.se',
+    'myhost-foo.tn.esss.lu.se',
+    'myhost-02.tn.esss.lu.se',
+    'longhostname-100000000000.tn.esss.lu.se',
+    'a' * 62 + '.org',
+])
+def test_cname_re_valid(name):
+    assert validators.CNAME_RE.match(name) is not None
+
+
+@pytest.mark.parametrize('name', [
+    'myhost',
+    'myhost03',
+    'myhost.esss.lu.se.',
+    'myhost_foo.tn.esss.lu.se',
+    'a' * 63 + '.org',
+])
+def test_cname_re_invalid(name):
+    assert validators.CNAME_RE.match(name) is None